-
Notifications
You must be signed in to change notification settings - Fork 20k
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
siriak
merged 31 commits into
TheAlgorithms:master
from
Hardvan:non_preemptive_priority_scheduling.java
Oct 13, 2024
Merged
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 819e8a9
Update directory
Hardvan 26b8453
Merge branch 'master' into non_preemptive_priority_scheduling.java
Hardvan 7d6e777
Update directory
Hardvan 7541743
Fix clang errors
Hardvan 9220f11
Merge branch 'non_preemptive_priority_scheduling.java' of https://git…
Hardvan 27e7dbb
Fix trailing whitespace
Hardvan b4c1d7e
Fix
Hardvan f22f2f6
Fix semicolon
Hardvan b841d57
Fine tune test
Hardvan 30b141c
Fix build errors
Hardvan 1383847
Declare class as final
Hardvan 651be36
Merge branch 'master' into non_preemptive_priority_scheduling.java
Hardvan 5f68704
Update directory
Hardvan 0e2e34b
Fix comments
Hardvan 77ebd3a
Merge branch 'non_preemptive_priority_scheduling.java' of https://git…
Hardvan 80d3e0d
Add startTime
Hardvan 91e65c4
Merge branch 'master' into non_preemptive_priority_scheduling.java
Hardvan f90053a
Update directory
Hardvan 6b77dce
Fix
Hardvan 5daeb23
Merge remote-tracking branch 'origin/non_preemptive_priority_scheduli…
Hardvan def6fae
Fix
Hardvan 69a503e
Fix
Hardvan 45e809a
Merge remote-tracking branch 'origin/non_preemptive_priority_scheduli…
Hardvan 0449f10
Fix
Hardvan 03f10fa
Fix
Hardvan d28bc8f
Fix
Hardvan 34920f7
Fix
Hardvan de50d45
Fix
Hardvan f3ac28f
Fix
Hardvan c574498
Merge branch 'master' into non_preemptive_priority_scheduling.java
siriak File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
134 changes: 134 additions & 0 deletions
134
src/main/java/com/thealgorithms/scheduling/NonPreemptivePriorityScheduling.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} | ||
} |
70 changes: 70 additions & 0 deletions
70
src/test/java/com/thealgorithms/scheduling/NonPreemptivePrioritySchedulingTest.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.