响应比最高者优先算法(Highest Respone Patio First,HRRF)是介于这两种算法(FCFS和SJF)之间的一种折中的策略,既考虑了作业等待时间,又考虑了作业的运行时间,这样既照顾了短作业又不使长作业的等待时间过长,改进了调度性能。缺点是每次计算各道作业响应比会有一定的时间开销,需要估计期待的服务时间,性能要比SJF略差。
采用HRRF算法进行调度时,必须对输入井中的所有作业计算出各自的响应比,从资源能得到满足的作业中选择响应比最高的作业优先转入主存运行。
响应比的定义为:
响应比 = (作业等待时间 + 作业运行时间)/ 作业运行时间 ==> 响应比 = 作业响应时间 / 作业运行时间
作业从进入输入井到执行完成就是该作业的响应过程,因此该作业的响应时间就是作业的等待时间与运行时间之和。从响应比公式可以看出:
作业名 | 进入时间 | 运行时间/min |
---|---|---|
JOB2 | 50 | 50 |
JOB3 | 60 | 10 |
JOB1 | 0 | 120 |
JOB4 | 110 | 20 |
def Creat():
dic = {}
i = 0
while True:
name = input("请输入进程名(输入Z结束):")
if name == 'Z':
return dic
enter_time = eval(input("请输入进入时间:"))
run_time = eval(input("请输入运行时间:"))
values = {i:{'作业名': name,
'进入时间': enter_time,
'运行时间': run_time,
'开始时间': enter_time,
'完成时间': enter_time+run_time,
'周转时间': run_time,
'带权周转时间': 1}}
dic.update(values)
i += 1
创建一个大字典,大字典的键为数字,作为最后的输出顺序。而键所对应的值是字典类型的。用于储存作业的各个数据。
首先数据的初始化都默认是第一个作业被执行所生成的数据(方便找到第一个作业后可以直接跳过修改阶段)。
当作业名为Z时,作业的创建结束。
def first_sort(data):
for i in range(len(data)):
Min = data[i]
cnt = i
for j in range(i, len(data)):
if Min['进入时间'] > data[j]['进入时间']:
Min = data[j]
cnt = j
temp = data[i]
data[i] = Min
data[cnt] = temp
这一步比较有趣,我是以进入时间为对象,使用冒泡排序对作业进行排序。索引越小对应的键里的进入时间越早,即作业被创建的越早,索引值越小。
第一次排序后的结果
作业名 | 进入时间 | 运行时间/min |
---|---|---|
JOB1 | 0 | 120 |
JOB2 | 50 | 50 |
JOB3 | 60 | 10 |
JOB4 | 110 | 20 |
def Select_enter_time(data,finish,i):
dic = {}
for j in range(i, len(data)):
if finish >= data[j]['进入时间']:
ans = {j: data[j]}
dic.update(ans)
return dic
这一步可能会有些迷,但是又是必不可少的一步,少了这步就可能出现BUG(即还没创建就开始执行)。所以这一步就是在进行筛选,找出符合条件的作业。
def Response(Filter,finish,i):
MAX = (finish-Filter[i]['进入时间']+Filter[i]['运行时间'])/Filter[i]['运行时间']
MAX_cnt = i
for j in range(i, len(Filter)):
wait = finish-Filter[j]['进入时间']
res_time = (wait+Filter[j]['运行时间'])/Filter[j]['运行时间']
if MAX < res_time:
MAX = res_time
MAX_cnt = j
return MAX_cnt
在符合条件的作业下,找出响应比最大的作业的索引,因为在主函数中需要进行小字典(即作业)的交换。
def Write(data,finish,i):
data[i]['开始时间'] = finish
data[i]['完成时间'] = finish + data[i]['运行时间']
data[i]['周转时间'] = data[i]['完成时间'] - data[i]['进入时间']
data[i]['带权周转时间'] = data[i]['周转时间'] / data[i]['运行时间']
修改开始时间、完成时间、周转时间、带权周转时间。
def PPrint(data):
SZ,SD = 0, 0
for i in range(len(data)):
print(data[i])
SZ+=data[i]['周转时间']
SD+=data[i]['带权周转时间']
print("平均周转时间{0:.2f},平均带权周转时间{1:.2f}".format(SZ/len(data),SD/len(data)))
打印输出数据
def main():
data = Creat()
first_sort(data)
finish = data[0]['完成时间']
for i in range(1, len(data)):
Filter = Select_enter_time(data, finish, i)
if Filter == {}:
break
Index = Response(Filter, finish, i)
temp = data[i]
data[i] = Filter[Index]
data[Index] = temp
Write(data,finish,i)
finish = data[i]['完成时间']
PPrint(data)
if __name__ == '__main__':
main()
将Create()创建的作业赋值给data,然后对作业进行第一次排序first_sort(data),将第一个被执行作业的结束时间赋值给finish。进入for循环,每进行一次for循环,大字典{1:{作业},2:{作业},…,i:{作业}}已经排好执行顺序,这个for 循环相当于一个变形的顺序排序。
def Creat():
dic = {}
i = 0
while True:
name = input("请输入进程名(输入Z结束):")
if name == 'Z':
return dic
enter_time = eval(input("请输入进入时间:"))
run_time = eval(input("请输入运行时间:"))
values = {i:{'作业名': name,
'进入时间': enter_time,
'运行时间': run_time,
'开始时间': enter_time,
'完成时间': enter_time+run_time,
'周转时间': run_time,
'带权周转时间': 1}}
dic.update(values)
i += 1
def first_sort(data):
for i in range(len(data)):
Min = data[i]
cnt = i
for j in range(i, len(data)):
if Min['进入时间'] > data[j]['进入时间']:
Min = data[j]
cnt = j
temp = data[i]
data[i] = Min
data[cnt] = temp
def Select_enter_time(data,finish,i):
dic = {}
for j in range(i, len(data)):
if finish >= data[j]['进入时间']:
ans = {j: data[j]}
dic.update(ans)
return dic
def Response(Filter,finish,i):
MAX = (finish-Filter[i]['进入时间']+Filter[i]['运行时间'])/Filter[i]['运行时间']
MAX_cnt = i
for j in range(i, len(Filter)):
wait = finish-Filter[j]['进入时间']
res_time = (wait+Filter[j]['运行时间'])/Filter[j]['运行时间']
if MAX < res_time:
MAX = res_time
MAX_cnt = j
return MAX_cnt
def Write(data,finish,i):
data[i]['开始时间'] = finish
data[i]['完成时间'] = finish + data[i]['运行时间']
data[i]['周转时间'] = data[i]['完成时间'] - data[i]['进入时间']
data[i]['带权周转时间'] = data[i]['周转时间'] / data[i]['运行时间']
def PPrint(data):
SZ,SD = 0, 0
for i in range(len(data)):
print(data[i])
SZ+=data[i]['周转时间']
SD+=data[i]['带权周转时间']
print("平均周转时间{0:.2f},平均带权周转时间{1:.2f}".format(SZ/len(data),SD/len(data)))
def main():
data = Creat()
first_sort(data)
finish = data[0]['完成时间']
for i in range(1, len(data)):
Filter = Select_enter_time(data, finish, i)
if Filter == {}:
break
Index = Response(Filter, finish, i)
temp = data[i]
data[i] = Filter[Index]
data[Index] = temp
Write(data,finish,i)
finish = data[i]['完成时间']
PPrint(data)
if __name__ == '__main__':
main()
请输入进程名(输入Z结束):JOB1
请输入进入时间:0
请输入运行时间:120
请输入进程名(输入Z结束):JOB2
请输入进入时间:50
请输入运行时间:50
请输入进程名(输入Z结束):JOB3
请输入进入时间:60
请输入运行时间:10
请输入进程名(输入Z结束):JOB4
请输入进入时间:110
请输入运行时间:20
请输入进程名(输入Z结束):Z
{'作业名': 'JOB1', '进入时间': 0, '运行时间': 120, '开始时间': 0, '完成时间': 120, '周转时间': 120, '带权周转时间': 1}
{'作业名': 'JOB3', '进入时间': 60, '运行时间': 10, '开始时间': 120, '完成时间': 130, '周转时间': 70, '带权周转时间': 7.0}
{'作业名': 'JOB2', '进入时间': 50, '运行时间': 50, '开始时间': 130, '完成时间': 180, '周转时间': 130, '带权周转时间': 2.6}
{'作业名': 'JOB4', '进入时间': 110, '运行时间': 20, '开始时间': 180, '完成时间': 200, '周转时间': 90, '带权周转时间': 4.5}
平均周转时间102.50,平均带权周转时间3.77