Skip to content
Closed
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
98 changes: 98 additions & 0 deletions scheduling/shortest_remaining_time_first.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
"""
Shortest Remaining Time First (SRTF) Scheduling Algorithm.
SRTF is the preemptive version of Shortest Job First (SJF).
At every moment, the process with the smallest remaining burst time is executed.
https://en.wikipedia.org/wiki/Shortest_remaining_time
"""

from __future__ import annotations
from statistics import mean

Check failure on line 9 in scheduling/shortest_remaining_time_first.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (I001)

scheduling/shortest_remaining_time_first.py:8:1: I001 Import block is un-sorted or un-formatted

Check failure on line 9 in scheduling/shortest_remaining_time_first.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (I001)

scheduling/shortest_remaining_time_first.py:8:1: I001 Import block is un-sorted or un-formatted


def calculate_waiting_times(burst_times: list[int], arrival_times: list[int]) -> list[int]:

Check failure on line 12 in scheduling/shortest_remaining_time_first.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (E501)

scheduling/shortest_remaining_time_first.py:12:89: E501 Line too long (91 > 88)

Check failure on line 12 in scheduling/shortest_remaining_time_first.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (E501)

scheduling/shortest_remaining_time_first.py:12:89: E501 Line too long (91 > 88)
"""
Calculate the waiting times of processes using SRTF scheduling.

Args:
burst_times: List of burst times for each process.
arrival_times: List of arrival times for each process.

Returns:
A list containing waiting time for each process.

Examples:
>>> calculate_waiting_times([6, 8, 7, 3], [0, 1, 2, 3])
[9, 15, 10, 0]
>>> calculate_waiting_times([5, 4, 2, 1], [0, 1, 2, 3])
[6, 3, 1, 0]
"""
n = len(burst_times)
remaining_times = burst_times.copy()
waiting_times = [0] * n
complete = 0
t = 0
min_remaining = float("inf")
shortest = 0
check = False
finish_time = 0

while complete != n:
# Find process with minimum remaining time at current time
for j in range(n):
if arrival_times[j] <= t and remaining_times[j] < min_remaining and remaining_times[j] > 0:

Check failure on line 42 in scheduling/shortest_remaining_time_first.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (E501)

scheduling/shortest_remaining_time_first.py:42:89: E501 Line too long (103 > 88)

Check failure on line 42 in scheduling/shortest_remaining_time_first.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (E501)

scheduling/shortest_remaining_time_first.py:42:89: E501 Line too long (103 > 88)
min_remaining = remaining_times[j]
shortest = j
check = True

if not check:
t += 1
continue

# Reduce remaining time of current process
remaining_times[shortest] -= 1
min_remaining = remaining_times[shortest]
if min_remaining == 0:
min_remaining = float("inf")

# If a process finishes
if remaining_times[shortest] == 0:
complete += 1
check = False
finish_time = t + 1
waiting_times[shortest] = (
finish_time - burst_times[shortest] - arrival_times[shortest]
)
if waiting_times[shortest] < 0:
waiting_times[shortest] = 0

Check failure on line 66 in scheduling/shortest_remaining_time_first.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (PLR1730)

scheduling/shortest_remaining_time_first.py:65:13: PLR1730 Replace `if` statement with `max` call

Check failure on line 66 in scheduling/shortest_remaining_time_first.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (PLR1730)

scheduling/shortest_remaining_time_first.py:65:13: PLR1730 Replace `if` statement with `max` call

t += 1

return waiting_times


def calculate_turn_around_times(
burst_times: list[int], waiting_times: list[int]
) -> list[int]:
"""
Calculate turn-around times for each process.

>>> calculate_turn_around_times([6, 8, 7, 3], [9, 15, 10, 0])
[15, 23, 17, 3]
"""
return [burst + waiting for burst, waiting in zip(burst_times, waiting_times)]


if __name__ == "__main__":
burst_times = [6, 8, 7, 3]
arrival_times = [0, 1, 2, 3]
waiting_times = calculate_waiting_times(burst_times, arrival_times)
turn_around_times = calculate_turn_around_times(burst_times, waiting_times)

print("Process ID \tArrival Time \tBurst Time \tWaiting Time \tTurnaround Time")
for i, burst_time in enumerate(burst_times):
print(
f" {i + 1}\t\t {arrival_times[i]}\t\t {burst_time}\t\t {waiting_times[i]}\t\t {turn_around_times[i]}"

Check failure on line 94 in scheduling/shortest_remaining_time_first.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (E501)

scheduling/shortest_remaining_time_first.py:94:89: E501 Line too long (118 > 88)

Check failure on line 94 in scheduling/shortest_remaining_time_first.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (E501)

scheduling/shortest_remaining_time_first.py:94:89: E501 Line too long (118 > 88)
)
print(f"\nAverage waiting time = {mean(waiting_times):.5f}")
print(f"Average turn around time = {mean(turn_around_times):.5f}")

Loading