python银行家算法1,判断是否存在安全序列
那个递归函数绝对是有问题的,只不过我自己也弄不明白,虽然是手搓的,但说实话我也不知道它为什么能运行🤣,然后里面的变量数值大部分都是字典,再加上二维列表,所以会有一大堆下标访问元素的代码,甚至我还用deepcopy库来实现字典的深度复制以完成递归,说实话这代码我看了都觉得low,但好歹能提交通过,侬死我了(家乡话),我想跑路进厂了😭,我宁愿拿个扳手敲敲打打也不愿意在这看一堆乱码,每天的问题就是这代码为什么不能运行?以及这代码为什么能运行?我的头发已经开始跑了,身体还没准备好😭,🆘🆘 代码在下边,注释是给漂亮女同学写的(虽然现在让我搞的关系有点紧张,不会说话的神经质😭,帮助同学帮助同学),我按照逻辑顺着写的,但其中应该会有我想不到的分支情况,具体需要深入研究,但我现在可能没太多时间,还要学其他的英语数学什么的,有人弄明白了可以随时私信我😘 你有一个思想,我有一个思想,我们互相交换,我们每个人都拥有了两个思想🥳 from copy import deepcopy N=int(input()) M=int(input()) # 存放资源最大值[10, 5, 7] source_all=list(map(int,input().split())) # 存放程序的资源分配和最大使用数据 dict_information={} for i in range(N): items=input().split() list_max=list(map(int,items[1:M+1])) #把输入的一行数据的第2个到第M个拿出来 list_allocation=list(map(int,items[M+1:])) # 把输入的第M个到第最后一个拿出来 list_need=[list_max[i]-list_allocation[i] for i in range(M)] #用最大减去已分配得到need dict_information[items[0]]=[list_max,list_allocation,list_need] # 把上面这三列表合成一个大列表放字典里 # dict_information存的数据 # ('P0', [[7, 5, 3], [0, 1, 0], [7, 4, 3]]) # ('P1', [[3, 2, 2], [2, 0, 0], [1, 2, 2]]) # ('P2', [[9, 0, 2], [3, 0, 2], [6, 0, 0]]) # ('P3', [[2, 2, 2], [2, 1, 1], [0, 1, 1]]) # ('P4', [[4, 3, 2], [0, 0, 2], [4, 3, 0]]) # 计算资源可用的数量 list_available=source_all for item in dict_information.items(): for i in range(M): list_available[i]-=item[1][1][i] # list_available=[3, 3, 2] #把need和数据拿出来放字典里等会计算用 dict_need={} dict_allocation={} for item in dict_information.items(): dict_need[item[0]]=item[1][2] dict_allocation[item[0]]=item[1][1] # 通过用list_available和不同程序的need匹配来判断是否可执行下一步 # 初步判断用递归 def find(dict_allocation,dict_need,list_available,M): if not dict_allocation.items():# 递归终止条件,因为下面的递归函数处每次将字典项目减一,所以当dict_allocation中的项目为0时表明所有进程都被选择过了,也就是都能运行 return 1 for i in dict_need.items(): list1=[1 if i[1][j]<=list_available[j] else 0 for j in range(M)] #因为有M个资源,需要每个资源都足够程序才能运行,所以用遍历判断满足条件的资源,满足就置1,不满足置0 if sum(list1)==M:# 在这里判断是不是所有资源都满足条件,也就是判断上边列表元素是不是都是1 # print(i[0],end=' ') dict_allocation_back=deepcopy(dict_allocation)# 以下四句都是为函数递归调用做准备,因为不想让原字典数据改变(因为一会还要输出用),又想进行函数递归调用(每次调用都将字典中的某一个满足运行条件的程序删除后再给函数用) del dict_allocation_back[i[0]] #删除满足条件的该程序(这里是i) dict_need_back=deepcopy(dict_need) del dict_need_back[i[0]]#这两句和上两句一样,都是把满足条件的这个程序删掉 status=find(dict_allocation_back,dict_need_back,[list_available[j]+dict_allocation.get(i[0])[j] for j in range(M)],M) # 函数递归调用 if status: # print(i[0]) # 只有当find返回1时该if语句才运行,而由于递归的存在,所有递归函数都停止在上面的status=find(dict_allocation_back,dict_need_back,[list_available[j]+dict_allocation.get(i[0])[j] for j in range(M)],M) #处等待子函数的返回,而我在函数开头定义了递归终止条件,所以当找递归到字典里没有程序的时候会返回1,然后父进程的status接收到return 1后,我用status接收,然后再次return 1, #然后层层返回1,最后结束return 1 return 1 else: return 0 if i==len(dict_need.items()): #当不存在一个安全序列时,也就是for循环中的满足条件的程序不存在,那么if不运行,字典也就不再减少内容,for循环里的return语句也就不会执行,那么for循环会运行到正常结束 #此时我通过判断i(这里的i就是for循环用的i)与字典长度相等得到没有满足条件的程序存在,所以我返回0,然后在父程序的for循环中的status收到return 0,那么父程序也会return 0, # 再次层层return 0,最后return 0 return 0 print("name max allocation need available") #这个a只是输出的时候第一行多个available,我让第一句和剩下的几句不一样输出,就加了个a a=1 for item in dict_information.items(): if a==1: a-=1 print(item[0],end=' ') print(*item[1][0],end=' | ') print(*item[1][1],end=' | ') print(*item[1][2],end=' | ') print(*list_available) else: print(item[0],end=' ') print(*item[1][0],end=' | ') print(*item[1][1],end=' | ') print(*item[1][2],end=' |') print() # 这里执行find函数判断是否有安全序列存在 if find(dict_allocation,dict_need,list_available,M): print("找到安全序列,处于安全状态。") else: print("找不到安全序列,处于不安全状态。")