0
点赞
收藏
分享

微信扫一扫

银行家算法c++完整代码

水沐由之 2022-03-31 阅读 102
c++

算法的核心:

一.安全性算法

安全性算法返回值为布尔类型,即调用时,如果当前系统安全,则返回true
1.初始化。.首先初始化进程的状态数组Finish[n]为false,数组Work[m]的初始值为当前系统资源的值
2.寻找可执行(未完成)的进程。用sum记录已完成进程的个数,用sum_flag记录遍历所有进程之后是否找到可执行的进程
   1)if (temp.Need[i][j] > Work[j]),则flag=false,跳到下一个进程;
    else (此时flag=true)  {sum_flag=true,即遍历一遍至少存在一个可执行的进程;释放该进程的资源,sum++;}
3.如果sum=进程数,则所有的进程都可执行,则当前系统处于安全状态
4.如果在执行完所有进程之前,遍历一遍所有进程无法找到可执行的进程(sum_flag=false),则当前系统处于不安全状态

二.资源分配算法
1.创建临时结构体temp,初始值为banker
2.判断系统现有的资源能否满足进程的申请
1)如果一个进程申请的某类资源可以满足,则为其分配资源
2)如果一个进程申请的各种资源无法同时满足,则撤回已为其分配的资源
3)如果一个进程申请的各种资源同时满足,(强掉一下,此时系统当前的资源已经被修改)则调用安全性算法,判断是否存在安全性序列
3.返回到系统的初始状态,继续测试(即满足其他进程的申请)

完整代码:

#include <iostream>
#include<iomanip>
#include <cstdlib>
using namespace std;
#define max_m 100
#define max_n 100
/*定义数据结构*/
typedef struct
{
	int Available[max_m];
	int Max[max_n][max_m];
	int Allocation[max_n][max_m];
	int Need[max_n][max_m];
	int Request[max_n][max_m];
	int n, m;
}Banker;
/*资源初始化*/
void Ini_resource(Banker& banker)
{
	srand(unsigned(time(0)));
	//cout << "请输入进程数和资源种类:";
		//cin >> banker.n >> banker.m;
	banker.n = 4;
	banker.m = 3;//这里按课本的实例了,如果要改,下面的输出格式(间隔)也要改
		for (int i = 0; i < banker.n; i++)
		{
			for (int j = 0; j < banker.m; j++)
			{
				banker.Allocation[i][j] = rand() % 3;//当前拥有的资源为0~2
				banker.Max[i][j] = rand() % 3+2;//最大的资源为2~4
				banker.Need[i][j] = banker.Max[i][j] - banker.Allocation[i][j];//需要的资源为0~4
				/*随机申请资源*/
				banker.Request[i][j] = rand() % 5;//申请的资源为0~4
				/*判断申请资源的合法性*/
				while (banker.Request[i][j] > banker.Need[i][j])
				{
					banker.Request[i][j] = rand() % 5;
				}
				/*系统现有资源只需要生成一次,这里在最后一个进程的初始化时生成*/
				if (i == banker.n - 1)
				{
					banker.Available[j] = rand() % 5;//系统当前拥有的资源为0~4
				}
			}
		}
	
}
/*打印函数*/
void print(Banker banker)
{
	cout << std::left << setw(13) << "进程 " << setw(30) << "Allocation" << setw(30) << "Max" << setw(30) << "Need" << setw(30) << "Request" << setw(30) << "Available" << endl;
	cout << std::left << setw(12) << "资源" << setw(6) << "r1" << setw(6) << "r2" << setw(6) << "r3" << setw(10) << "" << setw(6) << "r1" << setw(6) << "r2" << setw(6) << "r3" << setw(10) << "" << setw(6) << "r1" << setw(6) << "r2" << setw(6) << "r3" << setw(10) << "" << setw(6) << "r1" << setw(6) << "r2" << setw(6) << "r3" << setw(15) << "" << setw(6) << "r1" << setw(6) << "r2" << setw(6) << "r3" << endl;
	for (int i = 0; i < banker.n; i++)
	{
		cout << std::left << "P" << i << setw(10) << "";
		for (int j = 0; j < banker.m; j++)
			cout << setw(6) << banker.Allocation[i][j];
		cout << setw(10) << "";
		for (int j = 0; j < banker.m; j++)
			cout << setw(6) << banker.Max[i][j];
		cout << setw(10) << "";
		for (int j = 0; j < banker.m; j++)
			cout << setw(6) << banker.Need[i][j];
		cout << setw(10) << "";
		for (int j = 0; j < banker.m; j++)
			cout << setw(6) << banker.Request[i][j];
		/*系统资源只要打印一次*/
		if (i == 2)
		{
			cout << setw(15) << "";
			for (int j = 0; j < banker.m; j++)cout << setw(6) << banker.Available[j];
		}
		cout << endl;

	}
}
/*安全性算法*/
/*
	安全性算法返回值为布尔类型,即调用时,如果当前系统安全,则返回true
	1.初始化。.首先初始化进程的状态数组Finish[n]为false,数组Work[m]的初始值为当前系统资源的值
	2.寻找可执行(未完成)的进程。用sum记录已完成进程的个数,用sum_flag记录遍历所有进程之后是否找到可执行的进程
	   1)if (temp.Need[i][j] > Work[j]),则flag=false,跳到下一个进程;
	    else (此时flag=true)  {sum_flag=true,即遍历一遍至少存在一个可执行的进程;释放该进程的资源,sum++;}
	3.如果sum=进程数,则所有的进程都可执行,则当前系统处于安全状态
	4.如果在执行完所有进程之前,遍历一遍所有进程无法找到可执行的进程(sum_flag=false),则当前系统处于不安全状态
*/
bool Safety(Banker temp)//无需真实修改实参的值
{
	/*初始化进程状态,起初都为false*/
	bool Finish[max_n];
	for (int i = 0; i < temp.n; i++)Finish[i] = false;
	/*临时数组Work,初始值为Available*/
	int Work[max_m];
	for (int j = 0; j < temp.m; j++)Work[j] = temp.Available[j];
	
	cout << std::left << setw(13) << "进程 " << setw(30) << "Work" << setw(30) << "Need" << setw(30) << "Allocation" << setw(30) << "Work+Allocation" << setw(30) << "Finish" << endl;
	cout << std::left << setw(12) << "资源" << setw(6) << "r1" << setw(6) << "r2" << setw(6) << "r3" << setw(10) << "" << setw(6) << "r1" << setw(6) << "r2" << setw(6) << "r3" << setw(10) << "" << setw(6) << "r1" << setw(6) << "r2" << setw(6) << "r3" << setw(15) << "" << setw(6) << "r1" << setw(6) << "r2" << setw(6) << "r3" << endl;

	
	
	/*寻找可执行进程*/
	int sum = 0;
	while (sum != temp.n)//当还存在未完成的进程
	{
		bool sum_flag = false;//判断循环一遍之后是否有可执行的进程
		int i = 0;//while1循环一次就遍历一次所有的进程
		/*顺序寻找可执行的进程*/
		for (; i < temp.n; i++)
		{
			bool flag = true;//记录进程的所有条件是否被满足
			if (!Finish[i])
			{
				/*判断单进程的满足条件*/
				for (int j = 0; j < temp.m; j++)
				{
					if (temp.Need[i][j] > Work[j])
					{
						flag = false;
						break;
					}
				}

				if (flag)//如果满足单进程的所有需求
				{

					cout << std::left << "P" << i << setw(10) << "";
					for (int j = 0; j < temp.m; j++)
						cout << setw(6) << Work[j];
					cout << setw(10) << "";
					for (int j = 0; j < temp.m; j++)
						cout << setw(6) << temp.Need[i][j];
					cout << setw(10) << "";
					for (int j = 0; j < temp.m; j++)
						cout << setw(6) << temp.Allocation[i][j];
					cout << setw(15) << "";
					for (int j = 0; j < temp.m; j++)
						cout << setw(6) << Work[j] + temp.Allocation[i][j];
					cout << setw(15) << "" << "true" << endl;

					sum_flag = true;//有可执行的进程
					/*满足该进程的所有需求,即释放该进程的资源*/
					sum++;//进程可完成数+1
					Finish[i] = true;
					for (int j = 0; j < temp.m; j++)
					{
						Work[j] = Work[j] + temp.Allocation[i][j];//释放资源
					}

					if (sum == temp.n)//所有进程都可执行 
					{
						cout << "存在完整的安全序列,检测完毕." << endl; return true;
					};
				}
			}
		}
		if (!sum_flag) { cout << "循环一遍没找到可执行的进程,新系统状态不安全" << endl; return false; }
	}
}
/*资源分配算法
1.创建临时结构体temp,初始值为banker
2.判断系统现有的资源能否满足进程的申请
  1)如果一个进程申请的某类资源可以满足,则为其分配资源
  2)如果一个进程申请的各种资源无法同时满足,则撤回已为其分配的资源
  3)如果一个进程申请的各种资源同时满足,(强掉一下,此时系统当前的资源已经被修改)则调用安全性算法,判断是否存在安全性序列
3.返回到系统的初始状态,继续测试(即满足其他进程的申请)
*/
void Div_source(Banker& banker)
{
	cout << "系统的初始状态:" << endl;
	print(banker);
	cout << endl;
		/*创建临时结构体temp,初始值为banker*/
		Banker temp;
		temp.m = banker.m;
		temp.n = banker.n;
		for (int i = 0; i < banker.n; i++)
			for (int j = 0; j < banker.m; j++)
			{
				temp.Available[j] = banker.Available[j];
				temp.Allocation[i][j] = banker.Allocation[i][j];
				temp.Need[i][j] = banker.Need[i][j];
				temp.Max[i][j] = banker.Max[i][j];
				temp.Request[i][j] = banker.Request[i][j];
			}
		/*判断系统现有的资源能否满足进程的申请*/
		for (int i = 0; i < banker.n; i++)
		{
			bool flag = false;
			/*一个进程资源的分配*/
			for (int j = 0; j < banker.m; j++)
			{
				if (banker.Request[i][j] > banker.Available[j])
				{
					//该进程申请的资源j系统此刻无法满足,撤回re_j<j的资源
					// 跳到下一个进程
					for (int re_j = 0; re_j < j; re_j++)
					{
						temp.Available[re_j] = banker.Available[re_j];
						temp.Allocation[i][re_j] = banker.Allocation[i][re_j];
						temp.Need[i][re_j] = banker.Need[i][re_j];
						temp.Request[i][re_j] = banker.Request[i][re_j];
					}
					break;
				}

				/*如果一个进程申请的某类资源可以满足,则为其分配资源*/
				temp.Available[j] = temp.Available[j] - banker.Request[i][j];
				temp.Allocation[i][j] = temp.Allocation[i][j] + banker.Request[i][j];
				temp.Need[i][j] = temp.Need[i][j] - banker.Request[i][j];
				temp.Request[i][j] = 0;
				if (j == banker.m - 1) flag = true;
			}
			/*如果系统现有的资源满足进程的申请*/
			if (flag)
			{
				cout << "假设满足进程" << i << "申请的资源:";
				for (int j = 0; j < banker.m; j++)cout << banker.Request[i][j] << " ";
				cout << endl;

				cout << "此时系统的状态:" << endl;
				print(temp);

				cout << "系统安全情况分析:" << endl;
				/*调用安全性算法,判断是否要实际分配资源*/
				Safety(temp);//调用安全性算法的时候,此时系统的状态已经被修改

				cout << "撤回假设分配的资源,即回到系统的初始状态,继续测试" << endl;
				cout << endl;
				for (int yes_j = 0; yes_j < banker.m; yes_j++)
				{
					temp.Available[yes_j] = banker.Available[yes_j];
					temp.Allocation[i][yes_j] = banker.Allocation[i][yes_j];
					temp.Need[i][yes_j] = banker.Need[i][yes_j];
					temp.Request[i][yes_j] = banker.Request[i][yes_j];
				}
			}
			else
			{
				cout << "进程" << i << "申请的资源系统无法满足" << endl; 
				cout << endl;
			}
			
	
	}
}

int main()
{
	Banker banker;
	Ini_resource(banker);
	Div_source(banker);

}

运行效果图
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

举报

相关推荐

0 条评论