Skip to content

Add NonPreemptivePriorityScheduling new algorithm with unit tests #5535

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
4ce406f
Add NonPreemptivePriorityScheduling new algorithm with unit tests
Hardvan Oct 3, 2024
819e8a9
Update directory
Hardvan Oct 3, 2024
26b8453
Merge branch 'master' into non_preemptive_priority_scheduling.java
Hardvan Oct 3, 2024
7d6e777
Update directory
Hardvan Oct 3, 2024
7541743
Fix clang errors
Hardvan Oct 3, 2024
9220f11
Merge branch 'non_preemptive_priority_scheduling.java' of https://git…
Hardvan Oct 3, 2024
27e7dbb
Fix trailing whitespace
Hardvan Oct 3, 2024
b4c1d7e
Fix
Hardvan Oct 3, 2024
f22f2f6
Fix semicolon
Hardvan Oct 3, 2024
b841d57
Fine tune test
Hardvan Oct 3, 2024
30b141c
Fix build errors
Hardvan Oct 3, 2024
1383847
Declare class as final
Hardvan Oct 3, 2024
651be36
Merge branch 'master' into non_preemptive_priority_scheduling.java
Hardvan Oct 4, 2024
5f68704
Update directory
Hardvan Oct 4, 2024
0e2e34b
Fix comments
Hardvan Oct 4, 2024
77ebd3a
Merge branch 'non_preemptive_priority_scheduling.java' of https://git…
Hardvan Oct 4, 2024
80d3e0d
Add startTime
Hardvan Oct 6, 2024
91e65c4
Merge branch 'master' into non_preemptive_priority_scheduling.java
Hardvan Oct 6, 2024
f90053a
Update directory
Hardvan Oct 6, 2024
6b77dce
Fix
Hardvan Oct 6, 2024
5daeb23
Merge remote-tracking branch 'origin/non_preemptive_priority_scheduli…
Hardvan Oct 6, 2024
def6fae
Fix
Hardvan Oct 6, 2024
69a503e
Fix
Hardvan Oct 8, 2024
45e809a
Merge remote-tracking branch 'origin/non_preemptive_priority_scheduli…
Hardvan Oct 8, 2024
0449f10
Fix
Hardvan Oct 8, 2024
03f10fa
Fix
Hardvan Oct 8, 2024
d28bc8f
Fix
Hardvan Oct 8, 2024
34920f7
Fix
Hardvan Oct 8, 2024
de50d45
Fix
Hardvan Oct 9, 2024
f3ac28f
Fix
Hardvan Oct 9, 2024
c574498
Merge branch 'master' into non_preemptive_priority_scheduling.java
siriak Oct 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions DIRECTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
@@ -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
}
}