银行家算法(python实现)

禁止转载

考虑某个系统在下表时刻的状态

在这里插入图片描述
使用银行家算法回答下面的问题:

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("不安全")
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值