diff --git a/DIRECTORY.md b/DIRECTORY.md index a1a53cb2926c..46affca47109 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -36,6 +36,8 @@ * [OnesComplement](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/OnesComplement.java) * [ReverseBits](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/ReverseBits.java) * [SingleBitOperations](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/SingleBitOperations.java) + * [SingleElement](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/SingleElement.java) + * [SwapAdjacentBits](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/SwapAdjacentBits.java) * [TwosComplement](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/TwosComplement.java) * ciphers * a5 @@ -476,6 +478,7 @@ * Recursion * [GenerateSubsets](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/Recursion/GenerateSubsets.java) * scheduling + * [EDFScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/EDFScheduling.java) * [FCFSScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/FCFSScheduling.java) * [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) @@ -649,6 +652,8 @@ * [OnesComplementTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/OnesComplementTest.java) * [ReverseBitsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/ReverseBitsTest.java) * [SingleBitOperationsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/SingleBitOperationsTest.java) + * [SingleElementTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/SingleElementTest.java) + * [SwapAdjacentBitsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/SwapAdjacentBitsTest.java) * [TwosComplementTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/TwosComplementTest.java) * ciphers * a5 @@ -975,6 +980,7 @@ * Recursion * [GenerateSubsetsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/Recursion/GenerateSubsetsTest.java) * scheduling + * [EDFSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/EDFSchedulingTest.java) * [FCFSSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/FCFSSchedulingTest.java) * [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) diff --git a/src/main/java/com/thealgorithms/scheduling/EDFScheduling.java b/src/main/java/com/thealgorithms/scheduling/EDFScheduling.java new file mode 100644 index 000000000000..5ba79cdbb73a --- /dev/null +++ b/src/main/java/com/thealgorithms/scheduling/EDFScheduling.java @@ -0,0 +1,99 @@ +package com.thealgorithms.scheduling; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; + +/** + * The Earliest Deadline First (EDF) Scheduling class implements a dynamic scheduling algorithm. + * It assigns the CPU to processes with the earliest deadlines, ensuring that deadlines are met if possible. + * This scheduling algorithm is ideal for real-time systems where meeting deadlines is critical. + */ +public final class EDFScheduling { + private EDFScheduling() { + } + + private List processes; + + /** + * Constructs an EDFScheduling object with a list of processes. + * + * @param processes List of processes to be scheduled. + */ + public EDFScheduling(final List processes) { + this.processes = processes; + } + + /** + * Schedules the processes using Earliest Deadline First (EDF) scheduling. + * Processes are sorted by their deadlines, and the method simulates their execution. + * It calculates the waiting time and turnaround time for each process. + * + * @return List of processes after they have been executed in order of earliest deadline first. + */ + public List scheduleProcesses() { + processes.sort(Comparator.comparingInt(Process::getDeadline)); + + int currentTime = 0; + List executedProcesses = new ArrayList<>(); + + for (Process process : processes) { + process.setWaitingTime(currentTime); + currentTime += process.getBurstTime(); + process.setTurnAroundTime(process.getWaitingTime() + process.getBurstTime()); + + if (currentTime > process.getDeadline()) { + System.out.println("Warning: Process " + process.getProcessId() + " missed its deadline."); + } + + executedProcesses.add(process); + } + + return executedProcesses; + } + + /** + * The Process class represents a process with an ID, burst time, deadline, waiting time, and turnaround time. + */ + public static class Process { + private String processId; + private int burstTime; + private int deadline; + private int waitingTime; + private int turnAroundTime; + + public Process(String processId, int burstTime, int deadline) { + this.processId = processId; + this.burstTime = burstTime; + this.deadline = deadline; + } + + public String getProcessId() { + return processId; + } + + public int getBurstTime() { + return burstTime; + } + + public int getDeadline() { + return deadline; + } + + public int getWaitingTime() { + return waitingTime; + } + + public void setWaitingTime(int waitingTime) { + this.waitingTime = waitingTime; + } + + public int getTurnAroundTime() { + return turnAroundTime; + } + + public void setTurnAroundTime(int turnAroundTime) { + this.turnAroundTime = turnAroundTime; + } + } +} diff --git a/src/test/java/com/thealgorithms/scheduling/EDFSchedulingTest.java b/src/test/java/com/thealgorithms/scheduling/EDFSchedulingTest.java new file mode 100644 index 000000000000..8ce290cb246f --- /dev/null +++ b/src/test/java/com/thealgorithms/scheduling/EDFSchedulingTest.java @@ -0,0 +1,69 @@ +package com.thealgorithms.scheduling; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.ArrayList; +import java.util.List; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class EDFSchedulingTest { + + private List processes; + + @BeforeEach + public void setup() { + processes = createProcesses(); + } + + @Test + public void testEDFScheduling() { + EDFScheduling edfScheduling = new EDFScheduling(processes); + List executedProcesses = edfScheduling.scheduleProcesses(); + + // Assert the correct number of processes + assertEquals(3, executedProcesses.size()); + + // Assert that processes are executed in order of earliest deadline first + EDFScheduling.Process process1 = executedProcesses.get(0); + assertEquals("P2", process1.getProcessId()); + assertEquals(0, process1.getWaitingTime()); + assertEquals(3, process1.getTurnAroundTime()); + + EDFScheduling.Process process2 = executedProcesses.get(1); + assertEquals("P1", process2.getProcessId()); + assertEquals(3, process2.getWaitingTime()); + assertEquals(10, process2.getTurnAroundTime()); + + EDFScheduling.Process process3 = executedProcesses.get(2); + assertEquals("P3", process3.getProcessId()); + assertEquals(10, process3.getWaitingTime()); + assertEquals(18, process3.getTurnAroundTime()); + } + + @Test + public void testProcessMissedDeadline() { + // Modify the deadline of a process to ensure it will miss its deadline + processes.get(1).setTurnAroundTime(5); // Set P1's deadline to 5 (which it will miss) + + EDFScheduling edfScheduling = new EDFScheduling(processes); + edfScheduling.scheduleProcesses(); + + // Check if the process with ID "P1" missed its deadline + assertEquals("P1", processes.get(1).getProcessId()); + } + + private List createProcesses() { + // Process ID, Burst Time, Deadline + EDFScheduling.Process process1 = new EDFScheduling.Process("P1", 7, 10); // 7 burst time, 10 deadline + EDFScheduling.Process process2 = new EDFScheduling.Process("P2", 3, 5); // 3 burst time, 5 deadline + EDFScheduling.Process process3 = new EDFScheduling.Process("P3", 8, 18); // 8 burst time, 18 deadline + + List processes = new ArrayList<>(); + processes.add(process1); + processes.add(process2); + processes.add(process3); + + return processes; + } +}