Add NonPreemptivePriorityScheduling algorithm (#5535)

This commit is contained in:
Hardik Pawar
2024-10-14 02:35:12 +05:30
committed by GitHub
parent c301fec0ac
commit 213fd5a493
3 changed files with 206 additions and 0 deletions

View File

@ -505,6 +505,7 @@
* [HighestResponseRatioNextScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/HighestResponseRatioNextScheduling.java)
* [JobSchedulingWithDeadline](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/JobSchedulingWithDeadline.java)
* [MLFQScheduler](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/MLFQScheduler.java)
* [NonPreemptivePriorityScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/NonPreemptivePriorityScheduling.java)
* [PreemptivePriorityScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/PreemptivePriorityScheduling.java)
* [RRScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/RRScheduling.java)
* [SJFScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/SJFScheduling.java)
@ -1039,6 +1040,7 @@
* [HighestResponseRatioNextSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/HighestResponseRatioNextSchedulingTest.java)
* [JobSchedulingWithDeadlineTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/JobSchedulingWithDeadlineTest.java)
* [MLFQSchedulerTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/MLFQSchedulerTest.java)
* [NonPreemptivePrioritySchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/NonPreemptivePrioritySchedulingTest.java)
* [PreemptivePrioritySchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/PreemptivePrioritySchedulingTest.java)
* [RRSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/RRSchedulingTest.java)
* [SJFSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/SJFSchedulingTest.java)

View File

@ -0,0 +1,134 @@
package com.thealgorithms.scheduling;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Queue;
/**
* This class implements the Non-Preemptive Priority Scheduling algorithm.
* Processes are executed in order of their priority. The process with the
* highest priority (lower priority number) is executed first,
* and once a process starts executing, it cannot be preempted.
*/
public final class NonPreemptivePriorityScheduling {
private NonPreemptivePriorityScheduling() {
}
/**
* Represents a process with an ID, burst time, priority, arrival time, and start time.
*/
static class Process implements Comparable<Process> {
int id;
int arrivalTime;
int startTime;
int burstTime;
int priority;
/**
* Constructs a Process instance with the specified parameters.
*
* @param id Unique identifier for the process
* @param arrivalTime Time when the process arrives in the system
* @param burstTime Time required for the process execution
* @param priority Priority of the process
*/
Process(int id, int arrivalTime, int burstTime, int priority) {
this.id = id;
this.arrivalTime = arrivalTime;
this.startTime = -1;
this.burstTime = burstTime;
this.priority = priority;
}
/**
* Compare based on priority for scheduling. The process with the lowest
* priority is selected first.
* If two processes have the same priority, the one that arrives earlier is selected.
*
* @param other The other process to compare against
* @return A negative integer, zero, or a positive integer as this process
* is less than, equal to, or greater than the specified process.
*/
@Override
public int compareTo(Process other) {
if (this.priority == other.priority) {
return Integer.compare(this.arrivalTime, other.arrivalTime);
}
return Integer.compare(this.priority, other.priority);
}
}
/**
* Schedules processes based on their priority in a non-preemptive manner, considering their arrival times.
*
* @param processes Array of processes to be scheduled.
* @return Array of processes in the order they are executed.
*/
public static Process[] scheduleProcesses(Process[] processes) {
PriorityQueue<Process> pq = new PriorityQueue<>();
Queue<Process> waitingQueue = new LinkedList<>();
int currentTime = 0;
int index = 0;
Process[] executionOrder = new Process[processes.length];
for (Process process : processes) {
waitingQueue.add(process);
}
while (!waitingQueue.isEmpty() || !pq.isEmpty()) {
// Add processes that have arrived to the priority queue
while (!waitingQueue.isEmpty() && waitingQueue.peek().arrivalTime <= currentTime) {
pq.add(waitingQueue.poll());
}
if (!pq.isEmpty()) {
Process currentProcess = pq.poll();
currentProcess.startTime = currentTime;
executionOrder[index++] = currentProcess;
currentTime += currentProcess.burstTime;
} else {
// If no process is ready, move to the next arrival time
currentTime = waitingQueue.peek().arrivalTime;
}
}
return executionOrder;
}
/**
* Calculates the average waiting time of the processes.
*
* @param processes Array of processes.
* @param executionOrder Array of processes in execution order.
* @return Average waiting time.
*/
public static double calculateAverageWaitingTime(Process[] processes, Process[] executionOrder) {
int totalWaitingTime = 0;
for (Process process : executionOrder) {
int waitingTime = process.startTime - process.arrivalTime;
totalWaitingTime += waitingTime;
}
return (double) totalWaitingTime / processes.length;
}
/**
* Calculates the average turn-around time of the processes.
*
* @param processes Array of processes.
* @param executionOrder Array of processes in execution order.
* @return Average turn-around time.
*/
public static double calculateAverageTurnaroundTime(Process[] processes, Process[] executionOrder) {
int totalTurnaroundTime = 0;
for (Process process : executionOrder) {
int turnaroundTime = process.startTime + process.burstTime - process.arrivalTime;
totalTurnaroundTime += turnaroundTime;
}
return (double) totalTurnaroundTime / processes.length;
}
}

View File

@ -0,0 +1,70 @@
package com.thealgorithms.scheduling;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
public class NonPreemptivePrioritySchedulingTest {
@Test
public void testCalculateAverageWaitingTime() {
NonPreemptivePriorityScheduling.Process[] processes = {new NonPreemptivePriorityScheduling.Process(1, 0, 10, 2), // id, arrivalTime, burstTime, priority
new NonPreemptivePriorityScheduling.Process(2, 0, 5, 1), new NonPreemptivePriorityScheduling.Process(3, 0, 8, 3)};
NonPreemptivePriorityScheduling.Process[] executionOrder = NonPreemptivePriorityScheduling.scheduleProcesses(processes);
double expectedAvgWaitingTime = (0 + 5 + 15) / 3.0; // Waiting times: 0 for P2, 5 for P1, 15 for P3
double actualAvgWaitingTime = NonPreemptivePriorityScheduling.calculateAverageWaitingTime(processes, executionOrder);
assertEquals(expectedAvgWaitingTime, actualAvgWaitingTime, 0.01, "Average waiting time should be calculated correctly.");
}
@Test
public void testCalculateAverageTurnaroundTime() {
NonPreemptivePriorityScheduling.Process[] processes = {new NonPreemptivePriorityScheduling.Process(1, 0, 10, 2), // id, arrivalTime, burstTime, priority
new NonPreemptivePriorityScheduling.Process(2, 0, 5, 1), new NonPreemptivePriorityScheduling.Process(3, 0, 8, 3)};
NonPreemptivePriorityScheduling.Process[] executionOrder = NonPreemptivePriorityScheduling.scheduleProcesses(processes);
double expectedAvgTurnaroundTime = (5 + 15 + 23) / 3.0; // Turnaround times: 5 for P2, 15 for P1, 23 for P3
double actualAvgTurnaroundTime = NonPreemptivePriorityScheduling.calculateAverageTurnaroundTime(processes, executionOrder);
assertEquals(expectedAvgTurnaroundTime, actualAvgTurnaroundTime, 0.01, "Average turnaround time should be calculated correctly.");
}
@Test
public void testStartTimeIsCorrect() {
NonPreemptivePriorityScheduling.Process[] processes = {new NonPreemptivePriorityScheduling.Process(1, 0, 10, 2), // id, arrivalTime, burstTime, priority
new NonPreemptivePriorityScheduling.Process(2, 0, 5, 1), new NonPreemptivePriorityScheduling.Process(3, 0, 8, 3)};
NonPreemptivePriorityScheduling.Process[] executionOrder = NonPreemptivePriorityScheduling.scheduleProcesses(processes);
// Check that the start time for each process is correctly set
assertEquals(0, executionOrder[0].startTime, "First process (P2) should start at time 0."); // Process 2 has the highest priority
assertEquals(5, executionOrder[1].startTime, "Second process (P1) should start at time 5.");
assertEquals(15, executionOrder[2].startTime, "Third process (P3) should start at time 15.");
}
@Test
public void testWithDelayedArrivalTimes() {
NonPreemptivePriorityScheduling.Process[] processes = {new NonPreemptivePriorityScheduling.Process(1, 0, 4, 1), // id, arrivalTime, burstTime, priority
new NonPreemptivePriorityScheduling.Process(2, 2, 3, 2), new NonPreemptivePriorityScheduling.Process(3, 4, 2, 3)};
NonPreemptivePriorityScheduling.Process[] executionOrder = NonPreemptivePriorityScheduling.scheduleProcesses(processes);
// Test the start times considering delayed arrivals
assertEquals(0, executionOrder[0].startTime, "First process (P1) should start at time 0.");
assertEquals(4, executionOrder[1].startTime, "Second process (P2) should start at time 4."); // After P1 finishes
assertEquals(7, executionOrder[2].startTime, "Third process (P3) should start at time 7."); // After P2 finishes
}
@Test
public void testWithGapsInArrivals() {
NonPreemptivePriorityScheduling.Process[] processes = {new NonPreemptivePriorityScheduling.Process(1, 0, 6, 2), // id, arrivalTime, burstTime, priority
new NonPreemptivePriorityScheduling.Process(2, 8, 4, 1), new NonPreemptivePriorityScheduling.Process(3, 12, 5, 3)};
NonPreemptivePriorityScheduling.Process[] executionOrder = NonPreemptivePriorityScheduling.scheduleProcesses(processes);
// Test the start times for processes with gaps in arrival times
assertEquals(0, executionOrder[0].startTime, "First process (P1) should start at time 0.");
assertEquals(8, executionOrder[1].startTime, "Second process (P2) should start at time 8."); // After P1 finishes, arrives at 8
assertEquals(12, executionOrder[2].startTime, "Third process (P3) should start at time 12."); // After P2 finishes, arrives at 12
}
}