禁止转载
考虑某个系统在下表时刻的状态
使用银行家算法回答下面的问题:
Need矩阵是怎样的?
系统是否处于安全状态?若安全,请给出一个安全序列;若不安全,请给出理由。
若进程P1发来一个请求(0,4,2,0),这个请求能否被满足?若安全,请给出一个安全序列;若不安全,请给出理由。
这里以这个题目为参考,进行实验:
Python代码:
# 银行家算法
import numpy as np
def get_data(types_of_resources, process_nums):
print(types_of_resources, process_nums)
Max = np.zeros((process_nums,types_of_resources))
Allocation = np.zeros((process_nums,types_of_resources))
Need = np.zeros((process_nums,types_of_resources))
Available = np.zeros(types_of_resources)
print("请输入当前可用的各资源数目: ",end=" ")
nums_cnt = input().split()
nums_cnt = [int(i) for i in nums_cnt]
for i in range(types_of_resources):
Available[i]=nums_cnt[i]
for i in range(process_nums):
print(f"请输入P{i}的需要的最大资源数目:",end=" ")
nums_cnt = input().split()
nums_cnt = [int(i) for i in nums_cnt]
for j in range(types_of_resources):
Max[i][j] = nums_cnt[j]
for i in range(process_nums):
print(f"请输入P{i}已经分配的资源数目:", end=" ")
nums_cnt = input().split()
nums_cnt = [int(i) for i in nums_cnt]
for j in range(types_of_resources):
Allocation[i][j] = nums_cnt[j]
# 求取Need矩阵
for i in range(process_nums):
for j in range(types_of_resources):
Need[i][j] = Max[i][j] - Allocation[i][j]
draw_resource_map(Max, Allocation, Need, Available,types_of_resources, process_nums)
return Max, Allocation, Need, Available
def draw_resource_map(Max,Allocation,Need,Available,types_of_resources, process_nums):
kg_num = int(types_of_resources/2)+1
print("|---"+'-'*kg_num+"进程"+"--"+"最大需求"+"--"*kg_num+"已占有资源数目"+"--"*kg_num+"最多还需要分配"+"--"*kg_num+"各资源剩余数目"+"--|")
for i in range(process_nums):
print("| "*kg_num+"P"+str(i)+" "*kg_num+str(list(Max[i]))+" "*kg_num+str(list(Allocation[i]))+" "*kg_num+str(list(Need[i]))+str(list(Available))+" |")
return None
def main_banker_algorithm(Max, Allocation, Need, Available,types_of_resources, process_nums):
process_sequence = input("请输入请求分配的进程的序号(从0开始):")
process_sequence = int(process_sequence)
# 请求各个资源的数目
Requests = np.zeros(types_of_resources)
print("请输入请求的各个资源的数目:",end=" ")
nums_cnt = input().split()
nums_cnt = [int(i) for i in nums_cnt]
for j in range(types_of_resources):
Requests[j] = nums_cnt[j]
# 判断申请是否超过之前声明的最大需求出
# 检查此时系统剩余的可用资源是否满足这次请求
flag,Need_cnt,Allocation_cnt,Available_cnt = is_initial_conditions(Need,Allocation,Available,Requests,process_sequence,types_of_resources)
if not flag:
print("main~无法找到安全序列")
else:
# 先试着分配,看效果
analog_distribution(Max,Need_cnt,Allocation_cnt,Available_cnt,types_of_resources, process_nums)
return None
def is_initial_conditions(Need,Allocation,Available,Requests,process_sequence,types_of_resources):
Need_cnt = Need
Available_cnt = Available
Allocation_cnt = Allocation
for i in range(types_of_resources):
# 判断申请是否超过之前声明的最大需求出
if Requests[i] > Need[process_sequence][i]:
print("申请超过之前声明的最大需求")
return False
else:
Need_cnt[process_sequence][i]-=Requests[i]
# 检查此时系统剩余的可用资源是否满足这次请求
if Requests[i]>Available[i]:
print("此时系统剩余的可用资源不能满足这次请求")
return False
else:
Available_cnt[i]-=Requests[i]
Allocation_cnt[process_sequence][i]+=Requests[i]
return True,Need_cnt,Allocation_cnt,Available_cnt
def analog_distribution(Max,Need_cnt,Allocation_cnt,Available_cnt,types_of_resources, process_nums):
# 先找出满足现在当前序列的排在第一个进程
the_first_process = []
for i in range(process_nums):
flag = 0
for j in range(types_of_resources):
if (Available_cnt[j]>=Need_cnt[i][j]):
flag+=1
if(flag==types_of_resources):
the_first_process.append(i)
if len(the_first_process)==0:
print("没有找到安全序列")
else:
for rank in the_first_process:
Need, Allocation, Available = Need_cnt,Allocation_cnt,Available_cnt
# 记录进程是否执行完毕
process_over = [0]*process_nums
other = [i for i in range(process_nums) if i!=rank]
# 例子,剩下的三种,一共有6种排序方法,这里使用暴力大法(其实这里可以改善,不过没想到好的方法,嘻嘻)
# 应该是n!个方法
# 如果强行使用n!的暴力方法的话,我感觉是绕园路了,试下走一步弄一部吧
# 满足该进程后,彻底回收该进程使用的资源
for i in range(types_of_resources):
Available[i]+=Allocation[rank][i]
# 该进程执行完毕
process_over[rank] += 1
# 当前路径下的名称
road_name=[]
road_name.append(rank)
# 根据后面的序列判断是否存在合理的程序
isRight=True
# 用递归的方式查找对应的序列
look_for_reods(Need, Allocation, Available,process_over,len(other),road_name,isRight,types_of_resources, process_nums)
road_name.pop(-1)
process_over[rank] -= 1
for i in range(types_of_resources):
Available[i] -= Allocation[rank][i]
def look_for_reods(Need, Allocation, Available,process_over,geshu,road_name,isRight,types_of_resources, process_nums):
if isRight:
isRight_cnt=isRight
geshu_cnt = geshu
# 先找出满足现在当前序列的排在第一个进程
the_first_process = []
for i in range(process_nums):
if process_over[i]==0:
flag = 0
for j in range(types_of_resources):
if (Available[j] >= Need[i][j]):
flag += 1
if (flag == types_of_resources):
the_first_process.append(i)
if len(the_first_process) == 0 and len(road_name)!=process_nums:
print(str(list(road_name))+"没有找到安全序列")
isRight_cnt=False
for rank in the_first_process:
Need_cnt, Allocation_cnt, Available_cnt = Need.copy(), Allocation.copy(), Available.copy()
# 满足该进程后,彻底回收该进程使用的资源
for i in range(types_of_resources):
Available_cnt[i] += Allocation[rank][i]
# 该进程执行完毕
process_over[rank] += 1
road_name.append(rank)
geshu_cnt=geshu-1
if(geshu_cnt==0):
print("安全序列为:",end=" ")
print(road_name)
if isRight_cnt:
look_for_reods(Need_cnt, Allocation_cnt, Available_cnt, process_over, geshu_cnt, road_name, isRight_cnt,types_of_resources, process_nums)
road_name.pop(-1)
process_over[rank]-=1
def main():
types_of_resources , process_nums = input("请输入资源种类和进程数目:").split(" ")
types_of_resources, process_nums = int(types_of_resources) , int(process_nums)
Max, Allocation, Need, Available = get_data(types_of_resources, process_nums)
while True:
main_banker_algorithm(Max, Allocation, Need, Available,types_of_resources, process_nums)
return None
if __name__ == '__main__':
main()
实现效果
请输入资源种类和进程数目:4 4
4 4
请输入当前可用的各资源数目: 1 5 2 0
请输入P0的需要的最大资源数目: 0 0 1 2
请输入P1的需要的最大资源数目: 1 7 5 0
请输入P2的需要的最大资源数目: 2 3 5 6
请输入P3的需要的最大资源数目: 0 6 5 6
请输入P0已经分配的资源数目: 0 0 1 2
请输入P1已经分配的资源数目: 1 0 0 0
请输入P2已经分配的资源数目: 1 3 5 4
请输入P3已经分配的资源数目: 0 0 1 4
|------进程--最大需求------已占有资源数目------最多还需要分配------各资源剩余数目--|
| | | P0 [0.0, 0.0, 1.0, 2.0] [0.0, 0.0, 1.0, 2.0] [0.0, 0.0, 0.0, 0.0][1.0, 5.0, 2.0, 0.0] |
| | | P1 [1.0, 7.0, 5.0, 0.0] [1.0, 0.0, 0.0, 0.0] [0.0, 7.0, 5.0, 0.0][1.0, 5.0, 2.0, 0.0] |
| | | P2 [2.0, 3.0, 5.0, 6.0] [1.0, 3.0, 5.0, 4.0] [1.0, 0.0, 0.0, 2.0][1.0, 5.0, 2.0, 0.0] |
| | | P3 [0.0, 6.0, 5.0, 6.0] [0.0, 0.0, 1.0, 4.0] [0.0, 6.0, 4.0, 2.0][1.0, 5.0, 2.0, 0.0] |
请输入请求分配的进程的序号(从0开始):1
请输入请求的各个资源的数目: 0 4 2 0
安全序列为: [0, 2, 1, 3]
请输入请求分配的进程的序号(从0开始):
心得
- 忽然有点讨厌python的命名空间存储规则
使用ChatGPT生成的
# 银行家算法
def Banker_algorithm(available, max, allocation):
# available 可用资源数组
# max 每个进程最大需求资源数组
# allocation 已分配资源数组
# 返回:True:安全序列 False:不安全
Need = [] # 每个进程还需要资源
Work = available # 工作数组
Finish = [False] * len(allocation) # 完成情况
Safe_sequence = [] # 安全序列
# 计算每个进程还需要的资源
for i in range(len(allocation)):
Need.append([max[i][j] - allocation[i][j] for j in range(len(allocation[0]))])
# 找到一个安全序列
count = 0
while count < len(allocation):
# 找到一个进程,其Need<=Work
find = False
for i in range(len(allocation)):
if not Finish[i] and all([Need[i][j] <= Work[j] for j in range(len(Work))]):
# 将进程加入安全序列
Safe_sequence.append(i)
Finish[i] = True
# 更新工作数组
Work = [Work[j] + allocation[i][j] for j in range(len(Work))]
find = True
break
# 无法找到,返回False
if not find:
return False
count += 1
# 找到了安全序列,返回True
return True
# 实例
available = [3, 3, 2] # 可用资源
max = [[7, 5, 3], [3, 2, 2], [9, 0, 2], [2, 2, 2], [4, 3, 3]] # 每个进程最大需求资源
allocation = [[0, 1, 0], [2, 0, 0], [3, 0, 2], [2, 1, 1], [0, 0, 2]] # 已分配资源
if Banker_algorithm(available, max, allocation):
print("安全")
else:
print("不安全")