Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
102 changes: 102 additions & 0 deletions scheduling/preemptive_sjf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
"""
Shortest Remaining Time First (SRTF) scheduling is a preemptive version of
Shortest Job First (SJF).
At every unit of time, it selects the process with the smallest remaining
burst time among the processes that have arrived.

https://en.wikipedia.org/wiki/Shortest_job_next#Preemptive_SJF_(SRTF)
"""

from __future__ import annotations


def mean(values: list[int]) -> float:
"""
Return arithmetic mean of a list of numbers.

>>> mean([2, 4, 6, 8])
5.0
"""
return sum(values) / len(values)


def calculate_srtf_waiting_time(arrival: list[int], burst: list[int]) -> list[int]:
"""
Calculate waiting time for each process using Shortest Remaining Time First.

Args:
arrival: List of arrival times of processes.
burst: List of burst times of processes.

Returns:
List of waiting times for each process.

>>> calculate_srtf_waiting_time([0, 1, 2, 3], [8, 4, 9, 5])
[9, 0, 15, 2]
"""
n = len(arrival)
remaining = burst.copy()
waiting = [0] * n
completed = 0
t = 0
completion_time = [0] * n

while completed < n:
# Find process with smallest remaining time that has arrived
idx = -1
min_remaining = float("inf")
for i in range(n):
if arrival[i] <= t and remaining[i] > 0 and remaining[i] < min_remaining:
min_remaining = remaining[i]
idx = i

if idx == -1:
t += 1 # No process ready, advance time
continue

# Execute process for 1 unit of time
remaining[idx] -= 1
t += 1

# If process finished, record completion and calculate waiting
if remaining[idx] == 0:
completed += 1
completion_time[idx] = t
waiting[idx] = completion_time[idx] - arrival[idx] - burst[idx]

return waiting


def calculate_srtf_turnaround_time(burst: list[int], waiting: list[int]) -> list[int]:
"""
Calculate turnaround time for each process using waiting time.

Args:
burst: List of burst times.
waiting: List of waiting times.

Returns:
List of turnaround times.

>>> calculate_srtf_turnaround_time([8, 4, 9, 5], [9, 0, 15, 2])
[17, 4, 24, 7]
"""
return [burst[i] + waiting[i] for i in range(len(burst))]


if __name__ == "__main__":
arrival_time = [0, 1, 2, 3]
burst_time = [8, 4, 9, 5]

waiting_time = calculate_srtf_waiting_time(arrival_time, burst_time)
turnaround_time = calculate_srtf_turnaround_time(burst_time, waiting_time)

print("PID\tArrival\tBurst\tWaiting\tTurnaround")
for i in range(len(arrival_time)):
print(
f"P{i + 1}\t{arrival_time[i]}\t{burst_time[i]}\t"
f"{waiting_time[i]}\t{turnaround_time[i]}"
)

print(f"Average Waiting Time: {mean(waiting_time):.2f}")
print(f"Average Turnaround Time: {mean(turnaround_time):.2f}")
75 changes: 75 additions & 0 deletions scheduling/priority_scheduling.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
"""
Priority Scheduling assigns a priority to each process. The CPU is allocated
to the process with the highest priority (lowest number). It can be preemptive
or non-preemptive.
https://en.wikipedia.org/wiki/Priority_scheduling
"""


def mean(a):

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As there is no test file in this pull request nor any test function or class in the file scheduling/priority_scheduling.py, please provide doctest for the function mean

Please provide return type hint for the function: mean. If the function does not return a value, please provide the type hint as: def function() -> None:

Please provide descriptive name for the parameter: a

Please provide type hint for the parameter: a

return sum(a) / len(a)


def calculate_priority_waiting_time(arrival: list, burst: list, priority: list) -> list:
"""
Calculate waiting time for each process using preemptive priority scheduling.

>>> calculate_priority_waiting_time([0, 1, 2, 3], [10, 1, 2, 1], [3, 1, 4, 2])
[2, 0, 10, 0]
"""
n = len(arrival)
remaining = burst.copy()
waiting = [0] * n
complete = 0
t = 0

while complete < n:
idx = -1
highest_pri = float("inf")
for i in range(n):
if arrival[i] <= t and remaining[i] > 0 and priority[i] < highest_pri:
highest_pri = priority[i]
idx = i

if idx == -1:
t += 1
continue

remaining[idx] -= 1
t += 1

if remaining[idx] == 0:
complete += 1
waiting[idx] = t - arrival[idx] - burst[idx]

return waiting


def calculate_priority_turnaround_time(burst: list, waiting: list) -> list:
"""
Calculate turn around time for each process using waiting time.

>>> calculate_priority_turnaround_time([10, 1, 2, 1], [3, 0, 5, 1])
[13, 1, 7, 2]
"""
return [burst[i] + waiting[i] for i in range(len(burst))]


if __name__ == "__main__":
arrival_time = [0, 1, 2, 3]
burst_time = [10, 1, 2, 1]
priority = [3, 1, 4, 2]

waiting_time = calculate_priority_waiting_time(arrival_time, burst_time, priority)
turnaround_time = calculate_priority_turnaround_time(burst_time, waiting_time)

print("PID\tArrival\tBurst\tPriority\tWaiting\tTurnaround")
for i in range(len(arrival_time)):
print(
f"P{i + 1}\t{arrival_time[i]}\t{burst_time[i]}"
f"\t{priority[i]}\t\t{waiting_time[i]}"
f"\t{turnaround_time[i]}"
)

print(f"Average Waiting Time: {mean(waiting_time):.2f}")
print(f"Average Turnaround Time: {mean(turnaround_time):.2f}")