Skip to content

Commit 6b5f794

Browse files
committed
Add suggested changes
1 parent e4ec608 commit 6b5f794

File tree

2 files changed

+157
-74
lines changed

2 files changed

+157
-74
lines changed

src/main/java/com/thealgorithms/scheduling/HighestResponseRatioNextScheduling.java

Lines changed: 92 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -4,72 +4,109 @@
44
import java.util.Comparator;
55

66
/**
7-
* The HighestResponseRatioNextScheduling class implements
8-
* the Highest Response Ratio Next (HRRN) scheduling algorithm.
9-
* HRRN is a non-preemptive scheduling algorithm that
10-
* selects the process with the highest response ratio for execution.
11-
* The response ratio is calculated as (waiting time + burst time) / burst time.
12-
* This algorithm aims to reduce the average waiting time
13-
* and improve overall system performance by balancing short and long processes.
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.
1420
*/
1521
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+
1626
private HighestResponseRatioNextScheduling() {
1727
}
1828

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+
1958
/**
2059
* Calculates the Turn Around Time (TAT) for each process.
2160
*
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+
*
2265
* @param processNames Array of process names.
2366
* @param arrivalTimes Array of arrival times corresponding to each process.
24-
* @param burstTimes Array of burst times for each process.
67+
* @param burstTimes Array of burst times for each process.
2568
* @param noOfProcesses The number of processes.
2669
* @return An array of Turn Around Times for each process.
2770
*/
28-
public static int[] calculateTurnAroundTime(String[] processNames, int[] arrivalTimes, int[] burstTimes, int noOfProcesses) {
71+
public static int[] calculateTurnAroundTime(final String[] processNames, final int[] arrivalTimes, final int[] burstTimes, final int noOfProcesses) {
2972
int currentTime = 0;
3073
int[] turnAroundTime = new int[noOfProcesses];
31-
boolean[] finishedProcess = new boolean[noOfProcesses];
32-
int finishedProcessCount = 0;
33-
34-
// Sort by arrival times using a simple bubble sort for demonstration
35-
int[] sortedIndices = sortIndicesByArrival(arrivalTimes);
36-
arrivalTimes = Arrays.copyOf(arrivalTimes, arrivalTimes.length);
37-
burstTimes = Arrays.copyOf(burstTimes, burstTimes.length);
38-
processNames = Arrays.copyOf(processNames, processNames.length);
39-
40-
// Reorder the arrays based on sorted indices
41-
int[] tempArrival = new int[noOfProcesses];
42-
int[] tempBurst = new int[noOfProcesses];
43-
String[] tempProcess = new String[noOfProcesses];
74+
Process[] processes = new Process[noOfProcesses];
4475

4576
for (int i = 0; i < noOfProcesses; i++) {
46-
tempArrival[i] = arrivalTimes[sortedIndices[i]];
47-
tempBurst[i] = burstTimes[sortedIndices[i]];
48-
tempProcess[i] = processNames[sortedIndices[i]];
77+
processes[i] = new Process(processNames[i], arrivalTimes[i], burstTimes[i]);
4978
}
5079

51-
arrivalTimes = tempArrival;
52-
burstTimes = tempBurst;
53-
processNames = tempProcess;
80+
Arrays.sort(processes, Comparator.comparingInt(p -> p.arrivalTime));
5481

82+
int finishedProcessCount = 0;
5583
while (finishedProcessCount < noOfProcesses) {
56-
currentTime = Math.max(currentTime, arrivalTimes[findNextProcess(arrivalTimes, finishedProcess, currentTime)]);
57-
int loc = findHighestResponseRatio(processNames, arrivalTimes, burstTimes, finishedProcess, currentTime);
84+
int nextProcessIndex = findNextProcess(processes, currentTime);
85+
if (nextProcessIndex == PROCESS_NOT_FOUND) {
86+
currentTime++;
87+
continue;
88+
}
5889

59-
turnAroundTime[loc] = currentTime + burstTimes[loc] - arrivalTimes[loc];
60-
currentTime += burstTimes[loc];
61-
finishedProcess[loc] = true;
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;
6295
finishedProcessCount++;
6396
}
6497

98+
for (int i = 0; i < noOfProcesses; i++) {
99+
turnAroundTime[i] = processes[i].turnAroundTime;
100+
}
101+
65102
return turnAroundTime;
66103
}
67104

68105
/**
69106
* Calculates the Waiting Time (WT) for each process.
70107
*
71108
* @param turnAroundTime The Turn Around Times for each process.
72-
* @param burstTimes The burst times for each process.
109+
* @param burstTimes The burst times for each process.
73110
* @return An array of Waiting Times for each process.
74111
*/
75112
public static int[] calculateWaitingTime(int[] turnAroundTime, int[] burstTimes) {
@@ -83,58 +120,39 @@ public static int[] calculateWaitingTime(int[] turnAroundTime, int[] burstTimes)
83120
/**
84121
* Finds the next process to be scheduled based on arrival times and the current time.
85122
*
86-
* @param arrivalTimes Array of arrival times for each process.
87-
* @param finishedProcess Array indicating whether each process has finished.
88-
* @param currentTime The current time in the scheduling process.
89-
* @return The index of the next process to be scheduled.
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.
90126
*/
91-
private static int findNextProcess(int[] arrivalTimes, boolean[] finishedProcess, int currentTime) {
92-
for (int i = 0; i < arrivalTimes.length; i++) {
93-
if (!finishedProcess[i] && arrivalTimes[i] <= currentTime) {
94-
return i;
95-
}
96-
}
97-
return 0;
127+
private static int findNextProcess(Process[] processes, int currentTime) {
128+
return findHighestResponseRatio(processes, currentTime);
98129
}
99130

100131
/**
101132
* Finds the process with the highest response ratio.
102133
*
103-
* @param processNames Array of process names.
104-
* @param arrivalTimes Array of arrival times for each process.
105-
* @param burstTimes Array of burst times for each process.
106-
* @param finishedProcess Array indicating whether each process has finished.
107-
* @param currentTime The current time in the scheduling process.
108-
* @return The index of the process with the highest response ratio.
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.
109141
*/
110-
private static int findHighestResponseRatio(String[] processNames, int[] arrivalTimes, int[] burstTimes, boolean[] finishedProcess, int currentTime) {
111-
double maxResponseRatio = -1;
112-
int loc = -1;
142+
private static int findHighestResponseRatio(Process[] processes, int currentTime) {
143+
double maxResponseRatio = INITIAL_MAX_RESPONSE_RATIO;
144+
int maxIndex = PROCESS_NOT_FOUND;
113145

114-
for (int i = 0; i < processNames.length; i++) {
115-
if (!finishedProcess[i] && arrivalTimes[i] <= currentTime) {
116-
double responseRatio = (double) (burstTimes[i] + currentTime - arrivalTimes[i]) / burstTimes[i];
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);
117150
if (responseRatio > maxResponseRatio) {
118151
maxResponseRatio = responseRatio;
119-
loc = i;
152+
maxIndex = i;
120153
}
121154
}
122155
}
123-
return loc;
124-
}
125-
126-
/**
127-
* Sorts the indices of the arrival times array in ascending order.
128-
*
129-
* @param arrivalTimes Array of arrival times for each process.
130-
* @return An array of indices sorted by the corresponding arrival times.
131-
*/
132-
private static int[] sortIndicesByArrival(int[] arrivalTimes) {
133-
Integer[] indices = new Integer[arrivalTimes.length];
134-
for (int i = 0; i < arrivalTimes.length; i++) {
135-
indices[i] = i;
136-
}
137-
Arrays.sort(indices, Comparator.comparingInt(a -> arrivalTimes[a]));
138-
return Arrays.stream(indices).mapToInt(Integer::intValue).toArray();
156+
return maxIndex;
139157
}
140158
}

src/test/java/com/thealgorithms/scheduling/HighestResponseRatioNextSchedulingTest.java

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,69 @@ public void testCompleteSchedulingScenario() {
4444
int[] waitingTimes = HighestResponseRatioNextScheduling.calculateWaitingTime(turnAroundTimes, burstTimes);
4545
assertArrayEquals(expectedWaitingTimes, waitingTimes, "Waiting Times do not match");
4646
}
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+
}
47112
}

0 commit comments

Comments
 (0)