TheAlgorithms/C++ 1.0.0
All the algorithms implemented in C++
Loading...
Searching...
No Matches
non_preemptive_sjf_scheduling.cpp
Go to the documentation of this file.
1
14#include <algorithm>
15#include <cassert>
16#include <iomanip>
17#include <iostream>
18#include <queue>
19#include <random>
20#include <unordered_set>
21#include <vector>
22
23using std::cin;
24using std::cout;
25using std::endl;
26using std::get;
27using std::left;
28using std::make_tuple;
29using std::priority_queue;
30using std::tuple;
31using std::unordered_set;
32using std::vector;
33
44template <typename S, typename T, typename E>
45bool sortcol(tuple<S, T, E>& t1, tuple<S, T, E>& t2) {
46 if (get<1>(t1) < get<1>(t2) ||
47 (get<1>(t1) == get<1>(t2) && get<0>(t1) < get<0>(t2))) {
48 return true;
49 }
50 return false;
51}
52
60template <typename S, typename T, typename E>
61class Compare {
62 public:
74 bool operator()(tuple<S, T, E, double, double, double>& t1,
75 tuple<S, T, E, double, double, double>& t2) {
76 // Compare burst times for SJF
77 if (get<2>(t2) < get<2>(t1)) {
78 return true;
79 }
80 // If burst times are the same, compare arrival times
81 else if (get<2>(t2) == get<2>(t1)) {
82 return get<1>(t2) < get<1>(t1);
83 }
84 return false;
85 }
86};
87
95template <typename S, typename T, typename E>
96class SJF {
107 priority_queue<tuple<S, T, E, double, double, double>,
108 vector<tuple<S, T, E, double, double, double>>,
111
112 // Stores final status of all the processes after completing the execution.
113 vector<tuple<S, T, E, double, double, double>> result;
114
115 // Stores process IDs. Used for confirming absence of a process while it.
116 unordered_set<S> idList;
117
118 public:
127 void addProcess(S id, T arrival, E burst) {
128 // Add if a process with process ID as id is not found in idList.
129 if (idList.find(id) == idList.end()) {
130 tuple<S, T, E, double, double, double> t =
131 make_tuple(id, arrival, burst, 0, 0, 0);
132 schedule.push(t);
133 idList.insert(id);
134 }
135 }
136
154 vector<tuple<S, T, E, double, double, double>> scheduleForSJF() {
155 // Variable to keep track of time elapsed so far
156 double timeElapsed = 0;
157
158 while (!schedule.empty()) {
159 tuple<S, T, E, double, double, double> cur = schedule.top();
160
161 // If the current process arrived at time t2, the last process
162 // completed its execution at time t1, and t2 > t1.
163 if (get<1>(cur) > timeElapsed) {
164 timeElapsed += get<1>(cur) - timeElapsed;
165 }
166
167 // Add Burst time to time elapsed
168 timeElapsed += get<2>(cur);
169
170 // Completion time of the current process will be same as time
171 // elapsed so far
172 get<3>(cur) = timeElapsed;
173
174 // Turnaround time = Completion time - Arrival time
175 get<4>(cur) = get<3>(cur) - get<1>(cur);
176
177 // Waiting time = Turnaround time - Burst time
178 get<5>(cur) = get<4>(cur) - get<2>(cur);
179
180 // Turnaround time >= Burst time
181 assert(get<4>(cur) >= get<2>(cur));
182
183 // Waiting time is never negative
184 assert(get<5>(cur) >= 0);
185
186 result.push_back(cur);
187 schedule.pop();
188 }
189 return result;
190 }
198 const vector<tuple<S, T, E, double, double, double>>& processes) {
199 cout << std::setw(17) << left << "Process ID" << std::setw(17) << left
200 << "Arrival Time" << std::setw(17) << left << "Burst Time"
201 << std::setw(17) << left << "Completion Time" << std::setw(17)
202 << left << "Turnaround Time" << std::setw(17) << left
203 << "Waiting Time" << endl;
204
205 for (const auto& process : processes) {
206 cout << std::setprecision(2) << std::fixed << std::setw(17) << left
207 << get<0>(process) << std::setw(17) << left << get<1>(process)
208 << std::setw(17) << left << get<2>(process) << std::setw(17)
209 << left << get<3>(process) << std::setw(17) << left
210 << get<4>(process) << std::setw(17) << left << get<5>(process)
211 << endl;
212 }
213 }
214};
215
227template <typename S, typename T, typename E>
228vector<tuple<S, T, E, double, double, double>> get_final_status(
229 vector<tuple<S, T, E>> input) {
230 // Sort the processes based on Arrival time and then Burst time
231 sort(input.begin(), input.end(), sortcol<S, T, E>);
232
233 // Result vector to hold the final status of each process
234 vector<tuple<S, T, E, double, double, double>> result(input.size());
235 double timeElapsed = 0;
236
237 for (size_t i = 0; i < input.size(); i++) {
238 // Extract Arrival time and Burst time
239 T arrival = get<1>(input[i]);
240 E burst = get<2>(input[i]);
241
242 // If the CPU is idle, move time to the arrival of the next process
243 if (arrival > timeElapsed) {
244 timeElapsed = arrival;
245 }
246
247 // Update timeElapsed by adding the burst time
248 timeElapsed += burst;
249
250 // Calculate Completion time, Turnaround time, and Waiting time
251 double completion = timeElapsed;
252 double turnaround = completion - arrival;
253 double waiting = turnaround - burst;
254
255 // Store the results in the result vector
256 result[i] = make_tuple(get<0>(input[i]), arrival, burst, completion,
257 turnaround, waiting);
258 }
259
260 return result;
261}
262
267static void test() {
268 // A vector to store the results of all processes across all test cases.
269 vector<tuple<uint32_t, uint32_t, uint32_t, double, double, double>>
270 finalResult;
271
272 for (int i{}; i < 10; i++) {
273 std::random_device rd; // Seeding
274 std::mt19937 eng(rd());
275 std::uniform_int_distribution<> distr(1, 10);
276
277 uint32_t n = distr(eng);
279 vector<tuple<uint32_t, uint32_t, uint32_t, double, double, double>>
280 input(n);
281
282 // Generate random arrival and burst times
283 for (uint32_t i{}; i < n; i++) {
284 get<0>(input[i]) = i;
285 get<1>(input[i]) = distr(eng); // Random arrival time
286 get<2>(input[i]) = distr(eng); // Random burst time
287 }
288
289 // Print processes before scheduling
290 cout << "Processes before SJF scheduling:" << endl;
291 readyQueue.printResult(input);
292
293 // Add processes to the queue
294 for (uint32_t i{}; i < n; i++) {
295 readyQueue.addProcess(get<0>(input[i]), get<1>(input[i]),
296 get<2>(input[i]));
297 }
298
299 // Perform SJF schedulings
300 auto finalResult = readyQueue.scheduleForSJF();
301
302 // Print processes after scheduling
303 cout << "\nProcesses after SJF scheduling:" << endl;
304 readyQueue.printResult(finalResult);
305 }
306 cout << "All the tests have successfully passed!" << endl;
307}
308
313int main() {
314 test();
315 return 0;
316}
Comparator class for priority queue.
bool operator()(tuple< S, T, E, double, double, double > &t1, tuple< S, T, E, double, double, double > &t2)
A comparator function that checks whether to swap the two tuples or not. detailed description of comp...
Class which implements the SJF scheduling algorithm.
void printResult(const vector< tuple< S, T, E, double, double, double > > &processes)
Utility function for printing the status of each process after execution.
vector< tuple< S, T, E, double, double, double > > scheduleForSJF()
Algorithm for scheduling CPU processes according to the Shortest Job First (SJF) scheduling algorithm...
priority_queue< tuple< S, T, E, double, double, double >, vector< tuple< S, T, E, double, double, double > >, Compare< S, T, E > > schedule
void addProcess(S id, T arrival, E burst)
Adds the process to the ready queue if it isn't already there.
#define endl
bool sortcol(tuple< S, T, E > &t1, tuple< S, T, E > &t2)
Comparator function for sorting a vector.
vector< tuple< S, T, E, double, double, double > > get_final_status(vector< tuple< S, T, E > > input)
Computes the final status of processes after applying non-preemptive SJF scheduling.
static void test()
Self-test implementations.
int main()
Main function.