银行家算法

#include<stdio.h>
#include<stdlib.h>
#include<iostream>
using namespace std;
#define MAXSIZE 10
int n, m;//n是进程数,m是资源数
typedef struct{
	int Max[MAXSIZE][MAXSIZE];
	int Allocation[MAXSIZE][MAXSIZE];
	int Need[MAXSIZE][MAXSIZE];
	int program;
	int resource;
	int Available[MAXSIZE];
}BANK;

//输入条件
void init(BANK &banker){
	printf("进程数:");
	scanf("%d", &n);
	printf("资源数:");
	scanf("%d", &m);
	banker.program = n; banker.resource = m;

	printf("可利用资源:");
	for (int i = 0; i < banker.resource; i++)
		scanf("%d", &banker.Available[i]);
	
	printf("最大需求矩阵:\n");
	for (int i = 0; i < banker.program; i++){
		printf("进程P%d:", i);
		for (int j = 0; j < banker.resource; j++){
			scanf("%d", &banker.Max[i][j]);
		}
	}

	printf("分配矩阵:\n");
	for (int i = 0; i < banker.program; i++){
		printf("进程P%d:", i);
		for (int j = 0; j < banker.resource; j++){
			scanf("%d", &banker.Allocation[i][j]);
			//需求矩阵
			banker.Need[i][j] = banker.Max[i][j] - banker.Allocation[i][j];
			//还剩的可利用资源
			banker.Available[j] -= banker.Allocation[i][j];
		}
	}

	return;
}

//展示当前资源分配表
void shownow(BANK banker){
	printf("当前时刻资源分配表\n进程     Max        Allocation        Need        Available\n");//5,8,8,8
	int pause = 11 - banker.resource * 2;//空格,美观的的,没用
	for (int i = 0; i < banker.program; i++){
		printf("P%d       ", i);//空格7个
		for (int j = 0; j < banker.resource; j++)
			printf("%d ", banker.Max[i][j]);
		for (int j = 0; j < pause;j++)//对齐
		printf(" ");
		for (int j = 0; j < banker.resource; j++)
			printf("%d ", banker.Allocation[i][j]);
		for (int j = 0; j < (pause+7); j++)//对齐
			printf(" ");
		for (int j = 0; j < banker.resource; j++)
			printf("%d ", banker.Need[i][j]);
		if (i == 0){
			for (int j = 0; j < (pause + 1); j++)//对齐
				printf(" ");
			for (int j = 0; j < banker.resource; j++)
				printf("%d ", banker.Available[j]);
		}
			
		printf("\n");
	}
}
//展示当前的安全序列
void showSafe(int *safe, int Work[], BANK banker){
	printf("当前时刻安全序列\n进程     Work        Need        Allocation        Work+Allocation");
	int t = banker.program,k=0;
	int pause = 12 - banker.resource * 2;//空格,美观的的,没用
	for (int i = 0; i < banker.resource; i++)
		Work[i] = banker.Available[i];
	int temp;
	while (t--){
		temp = *(safe + k++);//进程号
		printf("\nP%d       ", temp);//空格7个
		for (int j = 0; j < banker.resource; j++)
			printf("%d ", Work[j]);
		for (int j = 0; j < pause; j++)//对齐
			printf(" ");
		for (int j = 0; j < banker.resource; j++)
			printf("%d ", banker.Need[temp][j]);
		for (int j = 0; j < pause; j++)//对齐
			printf(" ");
		for (int j = 0; j < banker.resource; j++){
			printf("%d ", banker.Allocation[temp][j]);
			Work[j] += banker.Allocation[temp][j];
		}
		for (int j = 0; j < (pause+6); j++)//对齐
			printf(" ");
		for (int j = 0; j < banker.resource; j++)
			printf("%d ", Work[j]);
	}
	printf("\n");
	return;
}

//比较a[]<=b[]是否都满足,多处应用到
bool compare(int a[], int b[]){
	for (int i = 0; i < m; i++){
		if (a[i]>b[i])return false;
	}
	return true;
}
//是否所有Finish[i]=true都满足
bool comp(bool a[]){
	for (int i = 0; i < n; i++)
		if (!a[i])return false;
	return true;
}

//分配
void GiveTo(BANK &banker,int pro[],int pro_id){
	for (int i = 0; i < banker.resource; i++){
		banker.Available[i] -= pro[i];
		banker.Allocation[pro_id][i] += pro[i];
		banker.Need[pro_id][i] -= pro[i];
	}
	return;
}
//取消分配
void GiveOut(BANK &banker, int pro[], int pro_id){
	for (int i = 0; i < banker.resource; i++){
		banker.Available[i] += pro[i];
		banker.Allocation[pro_id][i] -= pro[i];
		banker.Need[pro_id][i] += pro[i];
	}
	return;
}

//判断是否有进程达到最大需求,有就释放给它的资源,返回释放的进程号
int finishdoult(BANK &banker){
	int fh = -1;
	//判断是否有进程达到最大需求,fh记录进程号
	for (int i = 0; i < banker.program; i++){
		if (banker.Need[i][0] == 0){
			int j;
			for (j = 1; j < banker.resource; j++)
				if (banker.Need[i][j])break;
			if (j == banker.resource){
				fh = i; break;
			}
		}
	}

	if (fh == -1)return fh;
	for (int i = 0; i < banker.resource; i++){
		banker.Need[fh][i] = banker.Max[fh][i];
		banker.Allocation[fh][i] = 0;
		banker.Available[i] += banker.Max[fh][i];
	}
	return fh;
}

//只要有满足条件的执行即可,毕竟执行完可利用的资源只会变多
//安全性算法(银行家算法的步骤(4))
bool Savedoult(BANK banker,int *&safe){
	//3.1设置两个向量
	int Work[MAXSIZE],k=0;//k是保存安全序列的下标
	for (int i = 0; i < banker.resource; i++)
		Work[i] = banker.Available[i];
	bool Finish[MAXSIZE] = { false };

	//3.2:找一个满足条件的
	for (int i = 0; i < banker.program; i++){
		//找到,执行3.3
		if (!Finish[i] && compare(banker.Need[i], Work)){
			for (int j = 0; j < banker.resource; j++)
				Work[j] += banker.Allocation[i][j];
			Finish[i] = true;
			*(safe+k++) = i;//存入安全序列
			i = -1;//找到一个之后再从0开始循环(循环结束会++所以要设-1)
		}
		//没找到,执行3.4
		else{
			if (!comp(Finish))continue;
			//如果都满足了即安全,展示安全序列并返回true
			showSafe(safe, Work, banker);
			return true;
		}
	}
	//找不到安全序列则不安全
	return false;
}

//银行家算法
void banksafe(BANK &banker,int *safe){
	//步骤(0)请求(这里默认输入进程-1则退出)
	int pro_id, pro[MAXSIZE];
	printf("\n(-1则退出)进程:");
	cin >> pro_id;

	while (pro_id != -1){
		if (pro_id < 0 || pro_id >= banker.program){
			printf("超出进程数量限制\n进程:");
			cin >> pro_id;
			continue;
		}
		printf("进程P%d的请求变量:", pro_id);
		for (int i = 0; i < banker.resource; i++)
			scanf("%d", &pro[i]);

		//步骤(1)
		if (!compare(pro, banker.Need[pro_id])){
			printf("超出它所宣布的最大值\n进程:");
			cin >> pro_id;
			continue;
		}

		//步骤(2)
		if (!compare(pro, banker.Available)){
			printf("尚无足够资源,需等待\n进程:");
			cin >> pro_id;
			continue;
		}

		//步骤(3)试探的分配
		GiveTo(banker, pro, pro_id);

		//步骤(4)安全性算法
		if (Savedoult(banker, safe)){//若安全,正式分配,本次分配完成,输出安全序列和分配过后的资源分配表
			printf("安全\n安全序列:");
			for (int i = 0; i < banker.program; i++)
				printf("%d ", *(safe + i));
			printf("\n");
			int fh = finishdoult(banker);//是否有运行完毕的进程
			if (fh != -1){
				printf("进程P%d已运行完成,释放出分配给它的资源\n",fh);
			}
			shownow(banker);//展示当前资源分配表(运行完的释放,重新等待)
			printf("\n");
		}
		else{//若不安全,恢复原来的资源分配状态,等待该进程,执行其他的申请
			printf("不安全\n");
			GiveOut(banker, pro, pro_id);//取消分配
		}

		//步骤(0)请求
		printf("\n进程:");
		cin >> pro_id;

	}
	return;
}
int main(){
	BANK banker;
	init(banker);

	//判断当前时刻是否安全
	int *safe=(int*)malloc(n*sizeof(int));
	if (Savedoult(banker, safe)){
		printf("安全\n安全序列:");
		for (int i = 0; i < banker.program; i++)
			printf("%d ", *(safe + i));
		int fh = finishdoult(banker);//是否有运行完毕的进程
		if (fh != -1){
			printf("进程P%d已运行完成,释放出分配给它的资源\n", fh);
		}
		shownow(banker);//展示当前资源分配表(运行完的释放,重新等待)
		printf("\n");
	}
	else
		printf("不安全\n");

	banksafe(banker, safe);

	system("PAUSE");
	return 0;
}

0.结构体

#define MAXSIZE 10
int n, m;//n是进程数,m是资源数
typedef struct{
	int Max[MAXSIZE][MAXSIZE];
	int Allocation[MAXSIZE][MAXSIZE];
	int Need[MAXSIZE][MAXSIZE];
	int program;
	int resource;
	int Available[MAXSIZE];
}BANK;

1.输入条件

//输入条件
void init(BANK &banker){
	printf("进程数:");
	scanf("%d", &n);
	printf("资源数:");
	scanf("%d", &m);
	banker.program = n; banker.resource = m;

	printf("可利用资源:");
	for (int i = 0; i < banker.resource; i++)
		scanf("%d", &banker.Available[i]);
	
	printf("最大需求矩阵:\n");
	for (int i = 0; i < banker.program; i++){
		printf("进程P%d:", i);
		for (int j = 0; j < banker.resource; j++){
			scanf("%d", &banker.Max[i][j]);
		}
	}

	printf("分配矩阵:\n");
	for (int i = 0; i < banker.program; i++){
		printf("进程P%d:", i);
		for (int j = 0; j < banker.resource; j++){
			scanf("%d", &banker.Allocation[i][j]);
			//需求矩阵
			banker.Need[i][j] = banker.Max[i][j] - banker.Allocation[i][j];
			//还剩的可利用资源
			banker.Available[j] -= banker.Allocation[i][j];
		}
	}

	return;
}

2.展示当前时刻的资源分配表和安全序列

(安全序列的Work是在安全性算法中定义的,只能在安全性算法中引用)

//展示当前资源分配表
void shownow(BANK banker){
	printf("当前时刻资源分配表\n进程     Max        Allocation        Need        Available\n");//5,8,8,8
	int pause = 11 - banker.resource * 2;//空格,美观的的,没用
	for (int i = 0; i < banker.program; i++){
		printf("P%d       ", i);//空格7个
		for (int j = 0; j < banker.resource; j++)
			printf("%d ", banker.Max[i][j]);
		for (int j = 0; j < pause;j++)//对齐
		printf(" ");
		for (int j = 0; j < banker.resource; j++)
			printf("%d ", banker.Allocation[i][j]);
		for (int j = 0; j < (pause+7); j++)//对齐
			printf(" ");
		for (int j = 0; j < banker.resource; j++)
			printf("%d ", banker.Need[i][j]);
		if (i == 0){
			for (int j = 0; j < (pause + 1); j++)//对齐
				printf(" ");
			for (int j = 0; j < banker.resource; j++)
				printf("%d ", banker.Available[j]);
		}
			
		printf("\n");
	}
}
//展示当前的安全序列
void showSafe(int *safe, int Work[], BANK banker){
	printf("当前时刻安全序列\n进程     Work        Need        Allocation        Work+Allocation");
	int t = banker.program,k=0;
	int pause = 12 - banker.resource * 2;//空格,美观的的,没用
	for (int i = 0; i < banker.resource; i++)
		Work[i] = banker.Available[i];
	int temp;
	while (t--){
		temp = *(safe + k++);//进程号
		printf("\nP%d       ", temp);//空格7个
		for (int j = 0; j < banker.resource; j++)
			printf("%d ", Work[j]);
		for (int j = 0; j < pause; j++)//对齐
			printf(" ");
		for (int j = 0; j < banker.resource; j++)
			printf("%d ", banker.Need[temp][j]);
		for (int j = 0; j < pause; j++)//对齐
			printf(" ");
		for (int j = 0; j < banker.resource; j++){
			printf("%d ", banker.Allocation[temp][j]);
			Work[j] += banker.Allocation[temp][j];
		}
		for (int j = 0; j < (pause+6); j++)//对齐
			printf(" ");
		for (int j = 0; j < banker.resource; j++)
			printf("%d ", Work[j]);
	}
	printf("\n");
	return;
}

3.分配和取消分配

//分配
void GiveTo(BANK &banker,int pro[],int pro_id){
	for (int i = 0; i < banker.resource; i++){
		banker.Available[i] -= pro[i];
		banker.Allocation[pro_id][i] += pro[i];
		banker.Need[pro_id][i] -= pro[i];
	}
	return;
}
//取消分配
void GiveOut(BANK &banker, int pro[], int pro_id){
	for (int i = 0; i < banker.resource; i++){
		banker.Available[i] += pro[i];
		banker.Allocation[pro_id][i] -= pro[i];
		banker.Need[pro_id][i] += pro[i];
	}
	return;
}

4.两个比较函数,是否有运行完毕的进程

//比较a[]<=b[]是否都满足,多处应用到
bool compare(int a[], int b[]){
	for (int i = 0; i < m; i++){
		if (a[i]>b[i])return false;
	}
	return true;
}
//是否所有Finish[i]=true都满足
bool comp(bool a[]){
	for (int i = 0; i < n; i++)
		if (!a[i])return false;
	return true;
}
//判断是否有进程达到最大需求,有就释放给它的资源,返回释放的进程号
int finishdoult(BANK &banker){
	int fh = -1;
	//判断是否有进程达到最大需求,fh记录进程号
	for (int i = 0; i < banker.program; i++){
		if (banker.Need[i][0] == 0){
			int j;
			for (j = 1; j < banker.resource; j++)
				if (banker.Need[i][j])break;
			if (j == banker.resource){
				fh = i; break;
			}
		}
	}

	if (fh == -1)return fh;
	for (int i = 0; i < banker.resource; i++){
		banker.Need[fh][i] = banker.Max[fh][i];
		banker.Allocation[fh][i] = 0;
		banker.Available[i] += banker.Max[fh][i];
	}
	return fh;
}

5.安全性算法(银行家算法的步骤4)

只要有满足条件的执行即可,毕竟执行完可利用的资源只会变多
在这里插入图片描述

bool Savedoult(BANK banker,int *&safe){
	//3.1设置两个向量
	int Work[MAXSIZE],k=0;//k是保存安全序列的下标
	for (int i = 0; i < banker.resource; i++)
		Work[i] = banker.Available[i];
	bool Finish[MAXSIZE] = { false };

	//3.2:找一个满足条件的
	for (int i = 0; i < banker.program; i++){
		//找到,执行3.3
		if (!Finish[i] && compare(banker.Need[i], Work)){
			for (int j = 0; j < banker.resource; j++)
				Work[j] += banker.Allocation[i][j];
			Finish[i] = true;
			*(safe+k++) = i;//存入安全序列
			i = -1;//找到一个之后再从0开始循环(循环结束会++所以要设-1)
		}
		//没找到,执行3.4
		else{
			if (!comp(Finish))continue;
			//如果都满足了即安全,展示安全序列并返回true
			showSafe(safe, Work, banker);
			return true;
		}
	}
	//找不到安全序列则不安全
	return false;
}

6.银行家算法

在这里插入图片描述

//银行家算法
void banksafe(BANK &banker,int *safe){
	//步骤(0)请求(这里默认输入进程-1则退出)
	int pro_id, pro[MAXSIZE];
	printf("\n(-1则退出)进程:");
	cin >> pro_id;

	while (pro_id != -1){
		if (pro_id < 0 || pro_id >= banker.program){
			printf("超出进程数量限制\n进程:");
			cin >> pro_id;
			continue;
		}
		printf("进程P%d的请求变量:", pro_id);
		for (int i = 0; i < banker.resource; i++)
			scanf("%d", &pro[i]);

		//步骤(1)
		if (!compare(pro, banker.Need[pro_id])){
			printf("超出它所宣布的最大值\n进程:");
			cin >> pro_id;
			continue;
		}

		//步骤(2)
		if (!compare(pro, banker.Available)){
			printf("尚无足够资源,需等待\n进程:");
			cin >> pro_id;
			continue;
		}

		//步骤(3)试探的分配
		GiveTo(banker, pro, pro_id);

		//步骤(4)安全性算法
		if (Savedoult(banker, safe)){//若安全,正式分配,本次分配完成,输出安全序列和分配过后的资源分配表
			printf("安全\n安全序列:");
			for (int i = 0; i < banker.program; i++)
				printf("%d ", *(safe + i));
			printf("\n");
			int fh = finishdoult(banker);//是否有运行完毕的进程
			if (fh != -1){
				printf("进程P%d已运行完成,释放出分配给它的资源\n",fh);
			}
			shownow(banker);//展示当前资源分配表(运行完的释放,重新等待)
			printf("\n");
		}
		else{//若不安全,恢复原来的资源分配状态,等待该进程,执行其他的申请
			printf("不安全\n");
			GiveOut(banker, pro, pro_id);//取消分配
		}

		//步骤(0)请求
		printf("\n进程:");
		cin >> pro_id;

	}
	return;
}

7.主函数

int main(){
	BANK banker;
	init(banker);

	//判断当前时刻是否安全
	int *safe=(int*)malloc(n*sizeof(int));
	if (Savedoult(banker, safe)){
		printf("安全\n安全序列:");
		for (int i = 0; i < banker.program; i++)
			printf("%d ", *(safe + i));
		int fh = finishdoult(banker);//是否有运行完毕的进程
		if (fh != -1){
			printf("进程P%d已运行完成,释放出分配给它的资源\n", fh);
		}
		shownow(banker);//展示当前资源分配表(运行完的释放,重新等待)
		printf("\n");
	}
	else
		printf("不安全\n");

	banksafe(banker, safe);

	system("PAUSE");
	return 0;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Deosiree

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值