Repository: TheAlgorithms/Java
Pull request #4184 (2023-05-10 12:42:40)

add Round Robin Scheduling
<!-- For completed items, change [ ] to [x] -->

- [x] I have read [CONTRIBUTING.md](https://github.com/TheAlgorithms/Java/blob/master/CONTRIBUTING.md).
- [x] This pull request is all my own work -- I have not plagiarized it.
- [x] All filenames are in PascalCase.
- [x] All functions and variable names follow Java naming conventions.
- [x] All new algorithms have a URL in their comments that points to Wikipedia or other similar explanations.



Patch:
diff --git a/src/main/java/com/thealgorithms/scheduling/RRScheduling.java b/src/main/java/com/thealgorithms/scheduling/RRScheduling.java
new file mode 100644
index 00000000..6d26bfd7
--- /dev/null
+++ b/src/main/java/com/thealgorithms/scheduling/RRScheduling.java
@@ -0,0 +1,99 @@
+/**
+ * @author Md Asif Joardar
+ */
+
+package com.thealgorithms.scheduling;
+
+import com.thealgorithms.devutils.entities.ProcessDetails;
+
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Queue;
+
+/**
+ * The Round-robin scheduling algorithm is a kind of preemptive First come, First Serve CPU Scheduling algorithm.
+ * This can be understood here - https://www.scaler.com/topics/round-robin-scheduling-in-os/
+ */
+
+public class RRScheduling {
+    private List<ProcessDetails> processes;
+    private int quantumTime;
+
+    RRScheduling(final List<ProcessDetails> processes, int quantumTime) {
+        this.processes = processes;
+        this.quantumTime = quantumTime;
+    }
+
+    public void scheduleProcesses() {
+        evaluateTurnAroundTime();
+        evaluateWaitingTime();
+    }
+
+    private void evaluateTurnAroundTime() {
+        int processesNumber = processes.size();
+
+        if(processesNumber == 0) {
+            return;
+        }
+
+        Queue<Integer> queue = new LinkedList<>();
+        queue.add(0);
+        int currentTime = 0; // keep track of the time
+        int completed = 0;
+        int[] mark = new int[processesNumber];
+        Arrays.fill(mark, 0);
+        mark[0] = 1;
+
+        // a copy of burst time to store the remaining burst time
+        int[] remainingBurstTime = new int[processesNumber];
+        for (int i = 0; i < processesNumber; i++) {
+            remainingBurstTime[i] = processes.get(i).getBurstTime();
+        }
+
+        while (completed != processesNumber){
+            int index = queue.poll();
+
+            if(remainingBurstTime[index] == processes.get(index).getBurstTime()){
+                currentTime = Math.max(currentTime, processes.get(index).getArrivalTime());
+            }
+
+            if(remainingBurstTime[index] - quantumTime > 0){
+                remainingBurstTime[index] -= quantumTime;
+                currentTime += quantumTime;
+            } else {
+                currentTime += remainingBurstTime[index];
+                processes.get(index).setTurnAroundTimeTime(currentTime - processes.get(index).getArrivalTime());
+                completed++;
+                remainingBurstTime[index]=0;
+            }
+
+            // If some process has arrived when this process was executing, insert them into the queue.
+            for (int i=1; i < processesNumber; i++){
+                if(remainingBurstTime[i] > 0 && processes.get(i).getArrivalTime() <= currentTime && mark[i] == 0){
+                    mark[i]=1;
+                    queue.add(i);
+                }
+            }
+
+            // If the current process has burst time remaining, push the process into the queue again.
+            if(remainingBurstTime[index] > 0) queue.add(index);
+
+            // If the queue is empty, pick the first process from the list that is not completed.
+            if(queue.isEmpty()){
+                for (int i=1; i<processesNumber; i++){
+                    if (remainingBurstTime[i] > 0){
+                        mark[i] = 1;
+                        queue.add(i);
+                        break;
+                    }
+                }
+            }
+        }
+    }
+
+    private void evaluateWaitingTime() {
+        for (int i = 0; i < processes.size(); i++)
+            processes.get(i).setWaitingTime(processes.get(i).getTurnAroundTimeTime() - processes.get(i).getBurstTime());
+    }
+}


Test patch:
diff --git a/src/test/java/com/thealgorithms/scheduling/RRSchedulingTest.java b/src/test/java/com/thealgorithms/scheduling/RRSchedulingTest.java
new file mode 100644
index 00000000..935ff733
--- /dev/null
+++ b/src/test/java/com/thealgorithms/scheduling/RRSchedulingTest.java
@@ -0,0 +1,65 @@
+package com.thealgorithms.scheduling;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import com.thealgorithms.devutils.entities.ProcessDetails;
+import org.junit.jupiter.api.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+class RRSchedulingTest {
+    @Test
+    public void testingProcesses() {
+        List<ProcessDetails> processes = addProcessesForRR();
+        final RRScheduling rrScheduling = new RRScheduling(processes, 4); // for sending to RR with quantum value 4
+
+        rrScheduling.scheduleProcesses();
+
+        assertEquals(6, processes.size());
+
+        assertEquals("P1", processes.get(0).getProcessId());
+        assertEquals(12, processes.get(0).getWaitingTime());
+        assertEquals(17, processes.get(0).getTurnAroundTimeTime());
+
+        assertEquals("P2", processes.get(1).getProcessId());
+        assertEquals(16, processes.get(1).getWaitingTime());
+        assertEquals(22, processes.get(1).getTurnAroundTimeTime());
+
+        assertEquals("P3", processes.get(2).getProcessId());
+        assertEquals(6, processes.get(2).getWaitingTime());
+        assertEquals(9, processes.get(2).getTurnAroundTimeTime());
+
+        assertEquals("P4", processes.get(3).getProcessId());
+        assertEquals(8, processes.get(3).getWaitingTime());
+        assertEquals(9, processes.get(3).getTurnAroundTimeTime());
+
+        assertEquals("P5", processes.get(4).getProcessId());
+        assertEquals(15, processes.get(4).getWaitingTime());
+        assertEquals(20, processes.get(4).getTurnAroundTimeTime());
+
+        assertEquals("P6", processes.get(5).getProcessId());
+        assertEquals(11, processes.get(5).getWaitingTime());
+        assertEquals(15, processes.get(5).getTurnAroundTimeTime());
+
+    }
+
+    private List<ProcessDetails> addProcessesForRR() {
+        final ProcessDetails process1 = new ProcessDetails("P1", 0, 5);
+        final ProcessDetails process2 = new ProcessDetails("P2", 1, 6);
+        final ProcessDetails process3 = new ProcessDetails("P3", 2, 3);
+        final ProcessDetails process4 = new ProcessDetails("P4", 3, 1);
+        final ProcessDetails process5 = new ProcessDetails("P5", 4, 5);
+        final ProcessDetails process6 = new ProcessDetails("P6", 6, 4);
+
+        final List<ProcessDetails> processDetails = new ArrayList<>();
+        processDetails.add(process1);
+        processDetails.add(process2);
+        processDetails.add(process3);
+        processDetails.add(process4);
+        processDetails.add(process5);
+        processDetails.add(process6);
+
+        return processDetails;
+    }
+}
\ No newline at end of file