需求分析
设计一个程序将模拟实现FCFS(先来先服务)、SSTF(最短寻道时间优先)、电梯LOOK和C-SCAN(循环扫描)四种磁盘调度算法,并通过图形可视化界面动态展示每种算法的调度过程。
程序所能达到的功能;
实现FCFS、SSTF、电梯LOOK、C-SCAN四种磁盘调度算法。
计算并比较四种算法下磁头移动的总道数。
通过图形界面动态展示算法调度过程。
主程序流程
初始化磁头位置(start)。
调用 generate_requests() 函数生成磁道号序列。
分别调用 fcfs(),sstf(),look(),cscan() 来计算每种算法下的磁头移动道数,并获取移动路径。
比较并输出每种算法下的磁头移动道数。
使用图形库绘制可视化界面,展示每种算法的调度过程。
调用关系:
算法时间复杂性分析:
- FCFS:时间复杂度为O(n),因为只需遍历请求列表一次。
- SSTF:时间复杂性较高,因为每次选择下一个请求时都需要遍历整个请求列表。在最坏情况下,如果请求列表是按升序排列的,每次选择下一个请求时都需要遍历整个列表,时间复杂度为O(n^2)。
- LOOK:LOOK算法是SSTF的变种,它在同一方向移动时不会改变方向。其时间复杂性与SSTF类似,但通常性能会更好,因为它减少了不必要的方向切换。
- C-SCAN:C-SCAN算法按照一个方向扫描磁道,直到到达最远端,然后改变方向继续扫描。时间复杂性为O(n),因为磁头只需要遍历整个磁道范围两次(最坏情况下)。
运行结果:
FCFS algorithm movements: 63387
SSTF algorithm movements: 1677
LOOK algorithm movements: 2803
C-SCAN algorithm movements: 2966
源代码:
import random
import matplotlib.pyplot as plt
# 生成磁道号序列
def generate_requests():
requests = []
for i in range(200):
requests.append(random.randint(0, 499))
for i in range(100):
requests.append(random.randint(500, 999))
for i in range(100):
requests.append(random.randint(1000, 1499))
return requests
# FCFS 算法
def fcfs(requests, start):
movements = 0
current = start
movements_list = [current]
for request in requests:
movements += abs(request - current)
current = request
movements_list.append(current)
return movements, movements_list
# SSTF 算法
def sstf(requests, start):
movements = 0
current = start
movements_list = [current]
while requests:
next_request = min(requests, key=lambda x: abs(x - current))
movements += abs(next_request - current)
current = next_request
movements_list.append(current)
requests.remove(next_request)
return movements, movements_list
# 电梯 LOOK 算法
def look(requests, start):
if not requests:
return 0, [] # 如果请求列表为空,则返回0移动数和空列表
movements = 0
current = start
movements_list = [current]
direction = 1 # 1表示向外,-1表示向内
while requests:
if direction == 1:
next_request = min((x for x in requests if x >= current), default=None)
if next_request is None:
direction = -1
continue
else:
next_request = max((x for x in requests if x <= current), default=None)
if next_request is None:
direction = 1
continue
movements += abs(next_request - current)
current = next_request
movements_list.append(current)
requests.remove(next_request)
return movements, movements_list
# C-SCAN 算法
def cscan(requests, start):
if not requests:
return 0, []
sorted_requests = sorted([start] + requests)
current = start
movements = 0
movements_list = [start]
served = set([start])# 标记已服务的请求
for request in sorted_requests[1:]:
if request in served:
continue
movements += abs(request - current)
current = request
served.add(request)
movements_list.append(current)
if current != start:
movements += abs(start - current)
movements_list.append(start)
return movements, movements_list
#FCFS
# 生成磁道号序列
requests = generate_requests()
# 设置磁头初始位置
start = random.randint(0, 1499)
fcfs_movements, fcfs_movements_list = fcfs(requests, start)
print("FCFS algorithm movements:", fcfs_movements)
# 可视化界面
plt.figure(figsize=(10, 6))
plt.plot(range(len(fcfs_movements_list)), fcfs_movements_list, label='FCFS', marker='o', linestyle='-')
plt.title("Disk Scheduling Algorithms")
plt.xlabel("Time")
plt.ylabel("Disk Track")
plt.legend()
plt.show()
#SSTF
# 生成磁道号序列
requests = generate_requests()
# 设置磁头初始位置
start = random.randint(0, 1499)
sstf_movements, sstf_movements_list = sstf(requests, start)
print("SSTF algorithm movements:", sstf_movements)
# 可视化界面
plt.figure(figsize=(10, 6))
plt.plot(range(len(sstf_movements_list)), sstf_movements_list, label='SSTF', marker='x', linestyle='--')
plt.title("Disk Scheduling Algorithms")
plt.xlabel("Time")
plt.ylabel("Disk Track")
plt.legend()
plt.show()
#LOOK
# 生成磁道号序列
requests = generate_requests()
# 设置磁头初始位置
start = random.randint(0, 1499)
look_movements, look_movements_list = look(requests, start)
print("LOOK algorithm movements:", look_movements)
# 可视化界面
plt.figure(figsize=(10, 6))
plt.plot(range(len(look_movements_list)), look_movements_list, label='LOOK', marker='s', linestyle='-')
plt.title("Disk Scheduling Algorithms")
plt.xlabel("Time")
plt.ylabel("Disk Track")
plt.legend()
plt.show()
#cscan
# 生成磁道号序列
requests = generate_requests()
# 设置磁头初始位置
start = random.randint(0, 1499)
cscan_movements, cscan_movements_list = cscan(requests, start)
print("C-SCAN algorithm movements:", cscan_movements)
# 可视化界面
plt.figure(figsize=(10, 6))
plt.plot(range(len(cscan_movements_list)), cscan_movements_list, label='C-SCAN', marker='d', linestyle='-.')
plt.title("Disk Scheduling Algorithms")
plt.xlabel("Time")
plt.ylabel("Disk Track")
plt.legend()
plt.show()