银行家算法——输出所有安全序列

本文深入讲解银行家算法,探讨如何通过递归方式寻找所有安全序列,确保系统在资源分配过程中的安全性。文章提供了详细的代码实现,包括初始化资源、进程需求、资源分配与回溯过程,以及如何处理进程资源申请。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

银行家算法——输出所有安全序列

银行家算法的具体思路可见我的另一篇文章 点击了解

思路:递归从N个进程里选一个满足条件的进程作为一个安全序列的第一个元素,之后再各自从剩下的进程中选择满足条件的作为第二个元素……

问题:由于确定每一个安全序列、以及确定安全序列的每一个元素的过程中Finish[i]和Work[j]都在变化,所以需要一个撤回操作的步骤(回溯)

和深度优先搜索类似

代码如下

#include<string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define max 10
int PN;           //进程数
int RT;           //资源数
int Resourse[max];//资源种类
int Available[max];//系统剩余资源
int Work[max]; //工作向量
int Allocation[max][max];//进程已分配资源
int Need[max][max];//进程目前资源需求
int MAX[max][max];//进程最大资源需求
int Request[max];//申请
bool Finish[max];//完成标志
int sum;//安全序列计数
int choice;//选择申请资源
typedef struct
{
	int SafeOrder[max];
	int top;
}stack;
void push(stack *s, int x)
{
	s->SafeOrder[s->top] = x;
	s->top++;
}
void pop(stack *s)
{
	s->top--;
}
stack Order;
void printOrder()
{
	int i;
	sum++;
	if (sum == 1) printf("当前系统安全!\n");
	printf("第%d个安全序列: ", sum);
	for (i = 0; i < PN; i++)
	{
		if (i == 0)
			printf("P%d", Order.SafeOrder[i]);
		else
			printf("->P%d", Order.SafeOrder[i]);
	}
	printf("\n");
}
void IsSafe(int k)
{
	int i, j;
	if (k == PN)  //找到了一种安全性序列,打印输出
	{
		printOrder();
		return;
	}
	for (i = 0; i<PN; i++)
	{
		if (!Finish[i])
		{
			bool flag = true;
			for (j = 0; j<RT; j++)
				if (Need[i][j] > Work[j])
					flag = false;
			if (flag)//暂时放入安全性队列
			{
				for (j = 0; j < RT; j++)
					Work[j] += Allocation[i][j];
				Finish[i] = true;
				push(&Order, i + 1);//满足要求的进程放进安全序列
				IsSafe(k + 1);     //搜索下一个
				pop(&Order);       //回溯,将第i个进程所做的改变恢复,也就是弹出刚刚放进去的进程
				for (j = 0; j<RT; j++)
					Work[j] -= Allocation[i][j];
				Finish[i] = false;
			}
		}
	}
}
void Input(int a, int b, int c[max][max])
{
	int i, j;
	for (i = 0; i < b; i++)
		if (i == 0) printf("    R%d ", i + 1);
		else printf("R%d ", i + 1);
		printf("\n");
		for (i = 0; i < a; i++)
		{
			printf("P%d  ", i + 1);
			for (j = 0; j < b; j++)
				scanf("%d", &c[i][j]);
		}
}
void init()
{
	int i, j;
	sum = 0;
	Order.top = 0;
	printf("初始化: 请输入进程个数和资源总类: ");
	scanf("%d%d", &PN, &RT);
	printf("请输入各类资源数量: \n");
	for (i = 0; i < RT; i++)
		printf("R%d ", i + 1);
	printf("\n");
	for (i = 0; i < RT; i++)
		scanf("%d", &Resourse[i]);
	printf("请输入每个进程对每种资源的最大需求量:\n");
	Input(PN, RT, MAX);
	printf("请输入各类资源已分配量:\n");
	Input(PN, RT, Allocation);
	for (i = 0; i < PN; i++)
		for (j = 0; j < RT; j++)
			Need[i][j] = MAX[i][j] - Allocation[i][j];
	for (i = 0; i < RT; i++)
	{
		int s[max] = { 0 };
		for (j = 0; j < PN; j++)
			s[i] += Allocation[j][i];
		Available[i] = Resourse[i] - s[i];
		Work[i] = Available[i];
	}
	for (j = 0; j < PN; j++)
		Finish[i] = false;
}
bool  Apply()//进程资源申请
{
	int i;
	printf("选择申请资源的进程: P");
	scanf("%d", &choice);
	printf("输入各类资源申请数量\n");
	for (i = 0; i < RT; i++)
		printf("R%d ", i + 1);
	printf("\n");
	for (i = 0; i < RT; i++)
		scanf("%d", &Request[i]);
	for (i = 0; i < RT; i++)
		if (Request[i] <= Need[choice - 1][i])
		{
			if (Request[i] > Available[i])
			{
				printf("资源不足!"); return false;
			}

		}
		else//申请超出所需
		{
			printf("申请超出所需!"); return false;
		}
	return true;
}
bool banker()
{
	sum = 0;
	Order.top = 0;
	int i = choice - 1, j;
	for (j = 0; j < RT; j++)//试分配
	{
		Available[j] -= Request[j];
		Allocation[i][j] += Request[j];
		Need[i][j] -= Request[j];
		Work[j] = Available[j];
	}
	for (j = 0; j < PN; j++)
		Finish[j] = false;
	IsSafe(0);
	if (sum == 0)
	{
		for (j = 0; j < RT; j++)
		{
			Available[j] += Request[j];
			Allocation[i][j] -= Request[j];
			Need[i][j] += Request[j];
			Work[j] = Available[j];
		}
		return false;
	}
	return true;
}
void print()
{
	int i, j;
	printf("\n资源已分配|资源尚需: \n");
	for (i = 0; i < RT; i++)
		if (i == 0) printf("           R%d    ", i + 1);
		else printf("R%d    ", i + 1);
		printf("\n");
		for (i = 0; i < PN; i++)
		{
			printf("   P%d   :", i + 1);
			for (j = 0; j < RT; j++)
				printf("%2d|%-2d ", Allocation[i][j], Need[i][j]);
			printf("\n");
		}
		printf("系统剩余:");
		for (i = 0; i < RT; i++)
			printf("  %-4d", Available[i]);
		printf("\n");
}
void Menu()
{
	printf("------------------Banker-----------------------\n");
	printf("*              1.初始化数据                    *\n");
	printf("*              2.检验T0时刻安全性              *\n");
	printf("*              3.资源申请                      *\n");
	printf("*              4.退出                          *\n");
	printf("------------------------------------------------\n");
}
void  main()
{
	bool flag1, flag2;
	Menu();
Initialization:init();
	IsSafe(0);
	if (sum == 0)
	{
		printf("当前系统处于不安全状态,请重新初始化!\n");
		goto Initialization;

	}
	else print();
Application: flag1 = Apply();
	if (flag1)
	{
		flag2 = banker();
		if (!flag2)
		{
			printf("资源申请造成系统处不安全状态!申请失败!请重新申请\n");
			goto Application;
		}
		else
		{
			printf("申请成功!");
			print();
		}
	}
	else
	{
		printf("申请失败!请重新申请\n");
		goto Application;
	}
	int n;
	printf("是否还有进程申请资源? 是请输入1,否请输入0 :");
	scanf("%d", &n);
	if (n == 1)
		goto Application;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值