|
| 1 | +package com.thealgorithms.scheduling; |
| 2 | + |
| 3 | +import java.util.ArrayList; |
| 4 | +import java.util.Comparator; |
| 5 | +import java.util.List; |
1 | 6 | import java.util.PriorityQueue;
|
2 |
| -import java.util.Scanner; |
3 |
| - |
4 |
| -// Process class representing a process with attributes: id, weight, burst time, arrival time, and time received |
5 |
| -class Process { |
6 |
| - int id; |
7 |
| - int weight; |
8 |
| - int burstTime; |
9 |
| - int timeReceived; |
10 |
| - int arrivalTime; |
11 |
| - int priorityBoost; // Boost to prevent starvation |
12 |
| - |
13 |
| - public Process(int id, int weight, int burstTime, int arrivalTime) { |
14 |
| - this.id = id; |
15 |
| - this.weight = weight; |
16 |
| - this.burstTime = burstTime; |
17 |
| - this.arrivalTime = arrivalTime; |
18 |
| - this.timeReceived = 0; |
19 |
| - this.priorityBoost = 0; |
20 |
| - } |
21 |
| -} |
22 | 7 |
|
23 |
| -// Comparator to prioritize processes by weight and starvation prevention |
24 |
| -class ProcessComparator implements java.util.Comparator<Process> { |
25 |
| - @Override |
26 |
| - public int compare(Process p1, Process p2) { |
27 |
| - int effectiveWeight1 = p1.weight + p1.priorityBoost; |
28 |
| - int effectiveWeight2 = p2.weight + p2.priorityBoost; |
29 |
| - return Integer.compare(effectiveWeight2, effectiveWeight1); // Higher weight gets higher priority |
| 8 | +/** |
| 9 | + * The Proportional Share Scheduling (PSS) class implements a dynamic scheduling algorithm. |
| 10 | + * It assigns the CPU to processes based on their weight, ensuring that each process gets CPU time proportional to its weight. |
| 11 | + * The priority boost prevents starvation, ensuring that lower-weight processes still receive CPU time. |
| 12 | + */ |
| 13 | +public final class ProportionalShareScheduling { |
| 14 | + |
| 15 | + private ProportionalShareScheduling() { |
30 | 16 | }
|
31 |
| -} |
32 | 17 |
|
33 |
| -public class ProportionalShareScheduling { |
| 18 | + private List<Process> processes; |
34 | 19 |
|
35 |
| - // Method to implement the scheduling logic |
36 |
| - public static void proportionalShareScheduling(PriorityQueue<Process> readyQueue, int totalTimeQuantum) { |
| 20 | + /** |
| 21 | + * Constructs a ProportionalShareScheduling object with a list of processes. |
| 22 | + * |
| 23 | + * @param processes List of processes to be scheduled. |
| 24 | + */ |
| 25 | + public ProportionalShareScheduling(final List<Process> processes) { |
| 26 | + this.processes = processes; |
| 27 | + } |
| 28 | + |
| 29 | + /** |
| 30 | + * Schedules the processes using Proportional Share Scheduling (PSS). |
| 31 | + * Processes are scheduled based on their weight and priority boost. |
| 32 | + * It simulates their execution, calculates the waiting time, and ensures no starvation. |
| 33 | + * |
| 34 | + * @return List of processes after they have been executed in proportion to their weight. |
| 35 | + */ |
| 36 | + public List<Process> scheduleProcesses(int totalTimeQuantum) { |
| 37 | + PriorityQueue<Process> readyQueue = new PriorityQueue<>(new ProcessComparator()); |
| 38 | + readyQueue.addAll(processes); |
37 | 39 | int currentTime = 0;
|
| 40 | + List<Process> executedProcesses = new ArrayList<>(); |
| 41 | + |
38 | 42 | while (!readyQueue.isEmpty()) {
|
39 | 43 | Process current = readyQueue.poll();
|
40 |
| - |
41 |
| - // Determine time quantum to allocate to the current process |
42 |
| - int timeGiven = Math.min(current.weight, current.burstTime - current.timeReceived); |
43 | 44 |
|
| 45 | + // Determine time quantum to allocate to the current process |
| 46 | + int timeGiven = Math.min(current.getWeight(), current.getBurstTime() - current.getTimeReceived()); |
44 | 47 | currentTime += timeGiven;
|
45 |
| - current.timeReceived += timeGiven; |
| 48 | + current.setTimeReceived(current.getTimeReceived() + timeGiven); |
46 | 49 |
|
47 |
| - System.out.println("Process " + current.id + " received " + timeGiven + " units at time " + currentTime); |
| 50 | + System.out.println("Process " + current.getProcessId() + " received " + timeGiven + " units at time " + currentTime); |
48 | 51 |
|
49 | 52 | // If the process has finished execution
|
50 |
| - if (current.timeReceived >= current.burstTime) { |
51 |
| - System.out.println("Process " + current.id + " completed at time " + currentTime); |
| 53 | + if (current.getTimeReceived() >= current.getBurstTime()) { |
| 54 | + System.out.println("Process " + current.getProcessId() + " completed at time " + currentTime); |
52 | 55 | } else {
|
53 | 56 | // Starvation prevention: increase priority boost for unfinished processes
|
54 |
| - current.priorityBoost += 1; |
| 57 | + current.setPriorityBoost(current.getPriorityBoost() + 1); |
55 | 58 | readyQueue.add(current); // Reinsert into the queue for future execution
|
56 | 59 | }
|
57 | 60 |
|
58 | 61 | // Starvation prevention logic for all other processes in the queue
|
59 | 62 | for (Process p : readyQueue) {
|
60 |
| - p.priorityBoost += 1; // Increase the boost to prevent starvation |
| 63 | + p.setPriorityBoost(p.getPriorityBoost() + 1); // Increase the boost to prevent starvation |
61 | 64 | }
|
| 65 | + |
| 66 | + executedProcesses.add(current); |
62 | 67 | }
|
| 68 | + |
| 69 | + return executedProcesses; |
63 | 70 | }
|
64 | 71 |
|
65 |
| - public static void main(String[] args) { |
66 |
| - Scanner sc = new Scanner(System.in); |
| 72 | + /** |
| 73 | + * The Process class represents a process with an ID, weight, burst time, arrival time, time received, and priority boost. |
| 74 | + */ |
| 75 | + public static class Process { |
| 76 | + private String processId; |
| 77 | + private int weight; |
| 78 | + private int burstTime; |
| 79 | + private int arrivalTime; |
| 80 | + private int timeReceived; |
| 81 | + private int priorityBoost; |
| 82 | + |
| 83 | + public Process(String processId, int weight, int burstTime, int arrivalTime) { |
| 84 | + this.processId = processId; |
| 85 | + this.weight = weight; |
| 86 | + this.burstTime = burstTime; |
| 87 | + this.arrivalTime = arrivalTime; |
| 88 | + this.timeReceived = 0; |
| 89 | + this.priorityBoost = 0; |
| 90 | + } |
67 | 91 |
|
68 |
| - // Input number of processes |
69 |
| - System.out.print("Enter the number of processes: "); |
70 |
| - int n = sc.nextInt(); |
| 92 | + public String getProcessId() { |
| 93 | + return processId; |
| 94 | + } |
71 | 95 |
|
72 |
| - // Input total time quantum |
73 |
| - System.out.print("Enter the total time quantum: "); |
74 |
| - int totalTimeQuantum = sc.nextInt(); |
| 96 | + public int getWeight() { |
| 97 | + return weight; |
| 98 | + } |
75 | 99 |
|
76 |
| - // Create a priority queue to store processes based on the comparator |
77 |
| - PriorityQueue<Process> readyQueue = new PriorityQueue<>(new ProcessComparator()); |
| 100 | + public int getBurstTime() { |
| 101 | + return burstTime; |
| 102 | + } |
| 103 | + |
| 104 | + public int getArrivalTime() { |
| 105 | + return arrivalTime; |
| 106 | + } |
78 | 107 |
|
79 |
| - // Input the process details (id, weight, burst time, arrival time) |
80 |
| - for (int i = 0; i < n; i++) { |
81 |
| - System.out.println("Enter Process ID, Weight, Burst Time, Arrival Time for Process " + (i + 1) + ":"); |
82 |
| - int id = sc.nextInt(); |
83 |
| - int weight = sc.nextInt(); |
84 |
| - int burstTime = sc.nextInt(); |
85 |
| - int arrivalTime = sc.nextInt(); |
| 108 | + public int getTimeReceived() { |
| 109 | + return timeReceived; |
| 110 | + } |
| 111 | + |
| 112 | + public void setTimeReceived(int timeReceived) { |
| 113 | + this.timeReceived = timeReceived; |
| 114 | + } |
86 | 115 |
|
87 |
| - Process process = new Process(id, weight, burstTime, arrivalTime); |
88 |
| - readyQueue.add(process); // Add each process to the priority queue |
| 116 | + public int getPriorityBoost() { |
| 117 | + return priorityBoost; |
89 | 118 | }
|
90 | 119 |
|
91 |
| - // Call the scheduling function |
92 |
| - proportionalShareScheduling(readyQueue, totalTimeQuantum); |
| 120 | + public void setPriorityBoost(int priorityBoost) { |
| 121 | + this.priorityBoost = priorityBoost; |
| 122 | + } |
| 123 | + } |
93 | 124 |
|
94 |
| - sc.close(); |
| 125 | + /** |
| 126 | + * The ProcessComparator class compares processes based on their effective weight (weight + priority boost). |
| 127 | + */ |
| 128 | + public static class ProcessComparator implements Comparator<Process> { |
| 129 | + @Override |
| 130 | + public int compare(Process p1, Process p2) { |
| 131 | + int effectiveWeight1 = p1.getWeight() + p1.getPriorityBoost(); |
| 132 | + int effectiveWeight2 = p2.getWeight() + p2.getPriorityBoost(); |
| 133 | + return Integer.compare(effectiveWeight2, effectiveWeight1); // Higher weight gets higher priority |
| 134 | + } |
95 | 135 | }
|
96 | 136 | }
|
0 commit comments