Skip to content

Commit 2001a09

Browse files
Hardvanalxkm
andauthored
Add HighestResponseRatioNextScheduling.java new algorithm with tests (#5607)
* Add `HighestResponseRatioNextScheduling.java` new algorithm with tests * Update directory * Improve class documentation * Update directory * Fix * Fix * Fix * Add suggested changes * Fix clang errors --------- Co-authored-by: Hardvan <[email protected]> Co-authored-by: Alex Klymenko <[email protected]>
1 parent ee6cd64 commit 2001a09

File tree

3 files changed

+272
-0
lines changed

3 files changed

+272
-0
lines changed

DIRECTORY.md

+2
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,7 @@
459459
* [GenerateSubsets](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/Recursion/GenerateSubsets.java)
460460
* scheduling
461461
* [FCFSScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/FCFSScheduling.java)
462+
* [HighestResponseRatioNextScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/HighestResponseRatioNextScheduling.java)
462463
* [MLFQScheduler](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/MLFQScheduler.java)
463464
* [PreemptivePriorityScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/PreemptivePriorityScheduling.java)
464465
* [RRScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/RRScheduling.java)
@@ -916,6 +917,7 @@
916917
* [GenerateSubsetsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/Recursion/GenerateSubsetsTest.java)
917918
* scheduling
918919
* [FCFSSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/FCFSSchedulingTest.java)
920+
* [HighestResponseRatioNextSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/HighestResponseRatioNextSchedulingTest.java)
919921
* [MLFQSchedulerTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/MLFQSchedulerTest.java)
920922
* [PreemptivePrioritySchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/PreemptivePrioritySchedulingTest.java)
921923
* [RRSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/RRSchedulingTest.java)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
package com.thealgorithms.scheduling;
2+
3+
import java.util.Arrays;
4+
import java.util.Comparator;
5+
6+
/**
7+
* The {@code HighestResponseRatioNextScheduling} class implements the
8+
* Highest Response Ratio Next (HRRN) scheduling algorithm.
9+
* HRRN is a non-preemptive scheduling algorithm that selects the process with
10+
* the highest response ratio for execution.
11+
* The response ratio is calculated as:
12+
*
13+
* <pre>
14+
* Response Ratio = (waiting time + burst time) / burst time
15+
* </pre>
16+
*
17+
* HRRN is designed to reduce the average waiting time and improve overall
18+
* system performance by balancing between short and long processes,
19+
* minimizing process starvation.
20+
*/
21+
public final class HighestResponseRatioNextScheduling {
22+
23+
private static final int PROCESS_NOT_FOUND = -1;
24+
private static final double INITIAL_MAX_RESPONSE_RATIO = -1.0;
25+
26+
private HighestResponseRatioNextScheduling() {
27+
}
28+
29+
/**
30+
* Represents a process in the scheduling algorithm.
31+
*/
32+
private static class Process {
33+
String name;
34+
int arrivalTime;
35+
int burstTime;
36+
int turnAroundTime;
37+
boolean finished;
38+
39+
Process(String name, int arrivalTime, int burstTime) {
40+
this.name = name;
41+
this.arrivalTime = arrivalTime;
42+
this.burstTime = burstTime;
43+
this.turnAroundTime = 0;
44+
this.finished = false;
45+
}
46+
47+
/**
48+
* Calculates the response ratio for this process.
49+
*
50+
* @param currentTime The current time in the scheduling process.
51+
* @return The response ratio for this process.
52+
*/
53+
double calculateResponseRatio(int currentTime) {
54+
return (double) (burstTime + currentTime - arrivalTime) / burstTime;
55+
}
56+
}
57+
58+
/**
59+
* Calculates the Turn Around Time (TAT) for each process.
60+
*
61+
* <p>Turn Around Time is calculated as the total time a process spends
62+
* in the system from arrival to completion. It is the sum of the burst time
63+
* and the waiting time.</p>
64+
*
65+
* @param processNames Array of process names.
66+
* @param arrivalTimes Array of arrival times corresponding to each process.
67+
* @param burstTimes Array of burst times for each process.
68+
* @param noOfProcesses The number of processes.
69+
* @return An array of Turn Around Times for each process.
70+
*/
71+
public static int[] calculateTurnAroundTime(final String[] processNames, final int[] arrivalTimes, final int[] burstTimes, final int noOfProcesses) {
72+
int currentTime = 0;
73+
int[] turnAroundTime = new int[noOfProcesses];
74+
Process[] processes = new Process[noOfProcesses];
75+
76+
for (int i = 0; i < noOfProcesses; i++) {
77+
processes[i] = new Process(processNames[i], arrivalTimes[i], burstTimes[i]);
78+
}
79+
80+
Arrays.sort(processes, Comparator.comparingInt(p -> p.arrivalTime));
81+
82+
int finishedProcessCount = 0;
83+
while (finishedProcessCount < noOfProcesses) {
84+
int nextProcessIndex = findNextProcess(processes, currentTime);
85+
if (nextProcessIndex == PROCESS_NOT_FOUND) {
86+
currentTime++;
87+
continue;
88+
}
89+
90+
Process currentProcess = processes[nextProcessIndex];
91+
currentTime = Math.max(currentTime, currentProcess.arrivalTime);
92+
currentProcess.turnAroundTime = currentTime + currentProcess.burstTime - currentProcess.arrivalTime;
93+
currentTime += currentProcess.burstTime;
94+
currentProcess.finished = true;
95+
finishedProcessCount++;
96+
}
97+
98+
for (int i = 0; i < noOfProcesses; i++) {
99+
turnAroundTime[i] = processes[i].turnAroundTime;
100+
}
101+
102+
return turnAroundTime;
103+
}
104+
105+
/**
106+
* Calculates the Waiting Time (WT) for each process.
107+
*
108+
* @param turnAroundTime The Turn Around Times for each process.
109+
* @param burstTimes The burst times for each process.
110+
* @return An array of Waiting Times for each process.
111+
*/
112+
public static int[] calculateWaitingTime(int[] turnAroundTime, int[] burstTimes) {
113+
int[] waitingTime = new int[turnAroundTime.length];
114+
for (int i = 0; i < turnAroundTime.length; i++) {
115+
waitingTime[i] = turnAroundTime[i] - burstTimes[i];
116+
}
117+
return waitingTime;
118+
}
119+
120+
/**
121+
* Finds the next process to be scheduled based on arrival times and the current time.
122+
*
123+
* @param processes Array of Process objects.
124+
* @param currentTime The current time in the scheduling process.
125+
* @return The index of the next process to be scheduled, or PROCESS_NOT_FOUND if no process is ready.
126+
*/
127+
private static int findNextProcess(Process[] processes, int currentTime) {
128+
return findHighestResponseRatio(processes, currentTime);
129+
}
130+
131+
/**
132+
* Finds the process with the highest response ratio.
133+
*
134+
* <p>The response ratio is calculated as:
135+
* (waiting time + burst time) / burst time
136+
* where waiting time = current time - arrival time</p>
137+
*
138+
* @param processes Array of Process objects.
139+
* @param currentTime The current time in the scheduling process.
140+
* @return The index of the process with the highest response ratio, or PROCESS_NOT_FOUND if no process is ready.
141+
*/
142+
private static int findHighestResponseRatio(Process[] processes, int currentTime) {
143+
double maxResponseRatio = INITIAL_MAX_RESPONSE_RATIO;
144+
int maxIndex = PROCESS_NOT_FOUND;
145+
146+
for (int i = 0; i < processes.length; i++) {
147+
Process process = processes[i];
148+
if (!process.finished && process.arrivalTime <= currentTime) {
149+
double responseRatio = process.calculateResponseRatio(currentTime);
150+
if (responseRatio > maxResponseRatio) {
151+
maxResponseRatio = responseRatio;
152+
maxIndex = i;
153+
}
154+
}
155+
}
156+
return maxIndex;
157+
}
158+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
package com.thealgorithms.scheduling;
2+
3+
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
4+
5+
import org.junit.jupiter.api.Test;
6+
7+
public class HighestResponseRatioNextSchedulingTest {
8+
9+
@Test
10+
public void testCalculateTurnAroundTime() {
11+
String[] processNames = {"A", "B", "C"};
12+
int[] arrivalTimes = {0, 2, 4};
13+
int[] burstTimes = {3, 1, 2};
14+
int noOfProcesses = 3;
15+
16+
int[] expectedTurnAroundTimes = {3, 2, 2};
17+
int[] actualTurnAroundTimes = HighestResponseRatioNextScheduling.calculateTurnAroundTime(processNames, arrivalTimes, burstTimes, noOfProcesses);
18+
19+
assertArrayEquals(expectedTurnAroundTimes, actualTurnAroundTimes, "Turn Around Times do not match");
20+
}
21+
22+
@Test
23+
public void testCalculateWaitingTime() {
24+
int[] turnAroundTimes = {3, 1, 5};
25+
int[] burstTimes = {3, 1, 2};
26+
27+
int[] expectedWaitingTimes = {0, 0, 3};
28+
int[] actualWaitingTimes = HighestResponseRatioNextScheduling.calculateWaitingTime(turnAroundTimes, burstTimes);
29+
30+
assertArrayEquals(expectedWaitingTimes, actualWaitingTimes, "Waiting Times do not match");
31+
}
32+
33+
@Test
34+
public void testCompleteSchedulingScenario() {
35+
String[] processNames = {"A", "B", "C"};
36+
int[] arrivalTimes = {0, 1, 2};
37+
int[] burstTimes = {5, 2, 1};
38+
39+
int[] expectedTurnAroundTimes = {5, 7, 4};
40+
int[] turnAroundTimes = HighestResponseRatioNextScheduling.calculateTurnAroundTime(processNames, arrivalTimes, burstTimes, processNames.length);
41+
assertArrayEquals(expectedTurnAroundTimes, turnAroundTimes, "Turn Around Times do not match");
42+
43+
int[] expectedWaitingTimes = {0, 5, 3};
44+
int[] waitingTimes = HighestResponseRatioNextScheduling.calculateWaitingTime(turnAroundTimes, burstTimes);
45+
assertArrayEquals(expectedWaitingTimes, waitingTimes, "Waiting Times do not match");
46+
}
47+
48+
@Test
49+
public void testZeroProcesses() {
50+
String[] processNames = {};
51+
int[] arrivalTimes = {};
52+
int[] burstTimes = {};
53+
int noOfProcesses = 0;
54+
55+
int[] expectedTurnAroundTimes = {};
56+
int[] actualTurnAroundTimes = HighestResponseRatioNextScheduling.calculateTurnAroundTime(processNames, arrivalTimes, burstTimes, noOfProcesses);
57+
58+
assertArrayEquals(expectedTurnAroundTimes, actualTurnAroundTimes, "Turn Around Times for zero processes should be an empty array");
59+
}
60+
61+
@Test
62+
public void testAllProcessesArriveAtSameTime() {
63+
String[] processNames = {"A", "B", "C", "D"};
64+
int[] arrivalTimes = {0, 0, 0, 0};
65+
int[] burstTimes = {4, 3, 1, 2};
66+
int noOfProcesses = 4;
67+
68+
int[] expectedTurnAroundTimes = {4, 10, 5, 7};
69+
int[] actualTurnAroundTimes = HighestResponseRatioNextScheduling.calculateTurnAroundTime(processNames, arrivalTimes, burstTimes, noOfProcesses);
70+
71+
assertArrayEquals(expectedTurnAroundTimes, actualTurnAroundTimes, "Turn Around Times for processes arriving at the same time do not match");
72+
}
73+
74+
@Test
75+
public void testProcessesWithZeroBurstTime() {
76+
String[] processNames = {"A", "B", "C"};
77+
int[] arrivalTimes = {0, 1, 2};
78+
int[] burstTimes = {3, 0, 2};
79+
int noOfProcesses = 3;
80+
81+
int[] expectedTurnAroundTimes = {3, 2, 3};
82+
int[] actualTurnAroundTimes = HighestResponseRatioNextScheduling.calculateTurnAroundTime(processNames, arrivalTimes, burstTimes, noOfProcesses);
83+
84+
assertArrayEquals(expectedTurnAroundTimes, actualTurnAroundTimes, "Turn Around Times for processes with zero burst time do not match");
85+
}
86+
87+
@Test
88+
public void testProcessesWithLargeGapsBetweenArrivals() {
89+
String[] processNames = {"A", "B", "C"};
90+
int[] arrivalTimes = {0, 100, 200};
91+
int[] burstTimes = {10, 10, 10};
92+
int noOfProcesses = 3;
93+
94+
int[] expectedTurnAroundTimes = {10, 10, 10};
95+
int[] actualTurnAroundTimes = HighestResponseRatioNextScheduling.calculateTurnAroundTime(processNames, arrivalTimes, burstTimes, noOfProcesses);
96+
97+
assertArrayEquals(expectedTurnAroundTimes, actualTurnAroundTimes, "Turn Around Times for processes with large gaps between arrivals do not match");
98+
}
99+
100+
@Test
101+
public void testProcessesWithVeryLargeBurstTimes() {
102+
String[] processNames = {"A", "B"};
103+
int[] arrivalTimes = {0, 1};
104+
int[] burstTimes = {Integer.MAX_VALUE / 2, Integer.MAX_VALUE / 2};
105+
int noOfProcesses = 2;
106+
107+
int[] expectedTurnAroundTimes = {Integer.MAX_VALUE / 2, Integer.MAX_VALUE - 2};
108+
int[] actualTurnAroundTimes = HighestResponseRatioNextScheduling.calculateTurnAroundTime(processNames, arrivalTimes, burstTimes, noOfProcesses);
109+
110+
assertArrayEquals(expectedTurnAroundTimes, actualTurnAroundTimes, "Turn Around Times for processes with very large burst times do not match");
111+
}
112+
}

0 commit comments

Comments
 (0)