Skip to content

Commit 213fd5a

Browse files
authored
Add NonPreemptivePriorityScheduling algorithm (#5535)
1 parent c301fec commit 213fd5a

File tree

3 files changed

+206
-0
lines changed

3 files changed

+206
-0
lines changed

DIRECTORY.md

+2
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,7 @@
505505
* [HighestResponseRatioNextScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/HighestResponseRatioNextScheduling.java)
506506
* [JobSchedulingWithDeadline](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/JobSchedulingWithDeadline.java)
507507
* [MLFQScheduler](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/MLFQScheduler.java)
508+
* [NonPreemptivePriorityScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/NonPreemptivePriorityScheduling.java)
508509
* [PreemptivePriorityScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/PreemptivePriorityScheduling.java)
509510
* [RRScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/RRScheduling.java)
510511
* [SJFScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/SJFScheduling.java)
@@ -1039,6 +1040,7 @@
10391040
* [HighestResponseRatioNextSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/HighestResponseRatioNextSchedulingTest.java)
10401041
* [JobSchedulingWithDeadlineTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/JobSchedulingWithDeadlineTest.java)
10411042
* [MLFQSchedulerTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/MLFQSchedulerTest.java)
1043+
* [NonPreemptivePrioritySchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/NonPreemptivePrioritySchedulingTest.java)
10421044
* [PreemptivePrioritySchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/PreemptivePrioritySchedulingTest.java)
10431045
* [RRSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/RRSchedulingTest.java)
10441046
* [SJFSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/SJFSchedulingTest.java)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
package com.thealgorithms.scheduling;
2+
3+
import java.util.LinkedList;
4+
import java.util.PriorityQueue;
5+
import java.util.Queue;
6+
7+
/**
8+
* This class implements the Non-Preemptive Priority Scheduling algorithm.
9+
* Processes are executed in order of their priority. The process with the
10+
* highest priority (lower priority number) is executed first,
11+
* and once a process starts executing, it cannot be preempted.
12+
*/
13+
public final class NonPreemptivePriorityScheduling {
14+
15+
private NonPreemptivePriorityScheduling() {
16+
}
17+
18+
/**
19+
* Represents a process with an ID, burst time, priority, arrival time, and start time.
20+
*/
21+
static class Process implements Comparable<Process> {
22+
int id;
23+
int arrivalTime;
24+
int startTime;
25+
int burstTime;
26+
int priority;
27+
28+
/**
29+
* Constructs a Process instance with the specified parameters.
30+
*
31+
* @param id Unique identifier for the process
32+
* @param arrivalTime Time when the process arrives in the system
33+
* @param burstTime Time required for the process execution
34+
* @param priority Priority of the process
35+
*/
36+
Process(int id, int arrivalTime, int burstTime, int priority) {
37+
this.id = id;
38+
this.arrivalTime = arrivalTime;
39+
this.startTime = -1;
40+
this.burstTime = burstTime;
41+
this.priority = priority;
42+
}
43+
44+
/**
45+
* Compare based on priority for scheduling. The process with the lowest
46+
* priority is selected first.
47+
* If two processes have the same priority, the one that arrives earlier is selected.
48+
*
49+
* @param other The other process to compare against
50+
* @return A negative integer, zero, or a positive integer as this process
51+
* is less than, equal to, or greater than the specified process.
52+
*/
53+
@Override
54+
public int compareTo(Process other) {
55+
if (this.priority == other.priority) {
56+
return Integer.compare(this.arrivalTime, other.arrivalTime);
57+
}
58+
return Integer.compare(this.priority, other.priority);
59+
}
60+
}
61+
62+
/**
63+
* Schedules processes based on their priority in a non-preemptive manner, considering their arrival times.
64+
*
65+
* @param processes Array of processes to be scheduled.
66+
* @return Array of processes in the order they are executed.
67+
*/
68+
public static Process[] scheduleProcesses(Process[] processes) {
69+
PriorityQueue<Process> pq = new PriorityQueue<>();
70+
Queue<Process> waitingQueue = new LinkedList<>();
71+
int currentTime = 0;
72+
int index = 0;
73+
Process[] executionOrder = new Process[processes.length];
74+
75+
for (Process process : processes) {
76+
waitingQueue.add(process);
77+
}
78+
79+
while (!waitingQueue.isEmpty() || !pq.isEmpty()) {
80+
// Add processes that have arrived to the priority queue
81+
while (!waitingQueue.isEmpty() && waitingQueue.peek().arrivalTime <= currentTime) {
82+
pq.add(waitingQueue.poll());
83+
}
84+
85+
if (!pq.isEmpty()) {
86+
Process currentProcess = pq.poll();
87+
currentProcess.startTime = currentTime;
88+
executionOrder[index++] = currentProcess;
89+
currentTime += currentProcess.burstTime;
90+
} else {
91+
// If no process is ready, move to the next arrival time
92+
currentTime = waitingQueue.peek().arrivalTime;
93+
}
94+
}
95+
96+
return executionOrder;
97+
}
98+
99+
/**
100+
* Calculates the average waiting time of the processes.
101+
*
102+
* @param processes Array of processes.
103+
* @param executionOrder Array of processes in execution order.
104+
* @return Average waiting time.
105+
*/
106+
public static double calculateAverageWaitingTime(Process[] processes, Process[] executionOrder) {
107+
int totalWaitingTime = 0;
108+
109+
for (Process process : executionOrder) {
110+
int waitingTime = process.startTime - process.arrivalTime;
111+
totalWaitingTime += waitingTime;
112+
}
113+
114+
return (double) totalWaitingTime / processes.length;
115+
}
116+
117+
/**
118+
* Calculates the average turn-around time of the processes.
119+
*
120+
* @param processes Array of processes.
121+
* @param executionOrder Array of processes in execution order.
122+
* @return Average turn-around time.
123+
*/
124+
public static double calculateAverageTurnaroundTime(Process[] processes, Process[] executionOrder) {
125+
int totalTurnaroundTime = 0;
126+
127+
for (Process process : executionOrder) {
128+
int turnaroundTime = process.startTime + process.burstTime - process.arrivalTime;
129+
totalTurnaroundTime += turnaroundTime;
130+
}
131+
132+
return (double) totalTurnaroundTime / processes.length;
133+
}
134+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package com.thealgorithms.scheduling;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
5+
import org.junit.jupiter.api.Test;
6+
7+
public class NonPreemptivePrioritySchedulingTest {
8+
9+
@Test
10+
public void testCalculateAverageWaitingTime() {
11+
NonPreemptivePriorityScheduling.Process[] processes = {new NonPreemptivePriorityScheduling.Process(1, 0, 10, 2), // id, arrivalTime, burstTime, priority
12+
new NonPreemptivePriorityScheduling.Process(2, 0, 5, 1), new NonPreemptivePriorityScheduling.Process(3, 0, 8, 3)};
13+
NonPreemptivePriorityScheduling.Process[] executionOrder = NonPreemptivePriorityScheduling.scheduleProcesses(processes);
14+
15+
double expectedAvgWaitingTime = (0 + 5 + 15) / 3.0; // Waiting times: 0 for P2, 5 for P1, 15 for P3
16+
double actualAvgWaitingTime = NonPreemptivePriorityScheduling.calculateAverageWaitingTime(processes, executionOrder);
17+
18+
assertEquals(expectedAvgWaitingTime, actualAvgWaitingTime, 0.01, "Average waiting time should be calculated correctly.");
19+
}
20+
21+
@Test
22+
public void testCalculateAverageTurnaroundTime() {
23+
NonPreemptivePriorityScheduling.Process[] processes = {new NonPreemptivePriorityScheduling.Process(1, 0, 10, 2), // id, arrivalTime, burstTime, priority
24+
new NonPreemptivePriorityScheduling.Process(2, 0, 5, 1), new NonPreemptivePriorityScheduling.Process(3, 0, 8, 3)};
25+
26+
NonPreemptivePriorityScheduling.Process[] executionOrder = NonPreemptivePriorityScheduling.scheduleProcesses(processes);
27+
28+
double expectedAvgTurnaroundTime = (5 + 15 + 23) / 3.0; // Turnaround times: 5 for P2, 15 for P1, 23 for P3
29+
double actualAvgTurnaroundTime = NonPreemptivePriorityScheduling.calculateAverageTurnaroundTime(processes, executionOrder);
30+
31+
assertEquals(expectedAvgTurnaroundTime, actualAvgTurnaroundTime, 0.01, "Average turnaround time should be calculated correctly.");
32+
}
33+
34+
@Test
35+
public void testStartTimeIsCorrect() {
36+
NonPreemptivePriorityScheduling.Process[] processes = {new NonPreemptivePriorityScheduling.Process(1, 0, 10, 2), // id, arrivalTime, burstTime, priority
37+
new NonPreemptivePriorityScheduling.Process(2, 0, 5, 1), new NonPreemptivePriorityScheduling.Process(3, 0, 8, 3)};
38+
NonPreemptivePriorityScheduling.Process[] executionOrder = NonPreemptivePriorityScheduling.scheduleProcesses(processes);
39+
40+
// Check that the start time for each process is correctly set
41+
assertEquals(0, executionOrder[0].startTime, "First process (P2) should start at time 0."); // Process 2 has the highest priority
42+
assertEquals(5, executionOrder[1].startTime, "Second process (P1) should start at time 5.");
43+
assertEquals(15, executionOrder[2].startTime, "Third process (P3) should start at time 15.");
44+
}
45+
46+
@Test
47+
public void testWithDelayedArrivalTimes() {
48+
NonPreemptivePriorityScheduling.Process[] processes = {new NonPreemptivePriorityScheduling.Process(1, 0, 4, 1), // id, arrivalTime, burstTime, priority
49+
new NonPreemptivePriorityScheduling.Process(2, 2, 3, 2), new NonPreemptivePriorityScheduling.Process(3, 4, 2, 3)};
50+
NonPreemptivePriorityScheduling.Process[] executionOrder = NonPreemptivePriorityScheduling.scheduleProcesses(processes);
51+
52+
// Test the start times considering delayed arrivals
53+
assertEquals(0, executionOrder[0].startTime, "First process (P1) should start at time 0.");
54+
assertEquals(4, executionOrder[1].startTime, "Second process (P2) should start at time 4."); // After P1 finishes
55+
assertEquals(7, executionOrder[2].startTime, "Third process (P3) should start at time 7."); // After P2 finishes
56+
}
57+
58+
@Test
59+
public void testWithGapsInArrivals() {
60+
NonPreemptivePriorityScheduling.Process[] processes = {new NonPreemptivePriorityScheduling.Process(1, 0, 6, 2), // id, arrivalTime, burstTime, priority
61+
new NonPreemptivePriorityScheduling.Process(2, 8, 4, 1), new NonPreemptivePriorityScheduling.Process(3, 12, 5, 3)};
62+
63+
NonPreemptivePriorityScheduling.Process[] executionOrder = NonPreemptivePriorityScheduling.scheduleProcesses(processes);
64+
65+
// Test the start times for processes with gaps in arrival times
66+
assertEquals(0, executionOrder[0].startTime, "First process (P1) should start at time 0.");
67+
assertEquals(8, executionOrder[1].startTime, "Second process (P2) should start at time 8."); // After P1 finishes, arrives at 8
68+
assertEquals(12, executionOrder[2].startTime, "Third process (P3) should start at time 12."); // After P2 finishes, arrives at 12
69+
}
70+
}

0 commit comments

Comments
 (0)