"该代码开源免费,如有疑问欢迎咨询CSDN@一支王同学"
#include <iostream>
#include <string>
#include <stdlib.h>
using namespace std;
void Find_Security_Sequence(int, int, int*, int*, bool*, int**, int**);
void Dfs(int, int, int, int*, int*, int*, bool*, int**, int**);
void Print_Brief();
int flag = 0;
int all_Ans[101][101] = { 0 }; // 存储所有答案
int all_i = 0; // 答案下标, 总共有几种安全序列, all_i 就有多大
int main()
{
Print_Brief();
/*********************** 输入模块(开始) *********************************/
int n, m; // n 个进程, m 类资源
cout << "请分别输入进程数目和资料种类数 n 和 m 为:";
cin >> n >> m;
int* Resource = new int[m];
string* Res_name = new string[m];
cout << "请输入这" << m << "种资源分别的名称:";
for (int i = 0; i < m; i++)
cin >> Res_name[i];
cout << "请输入这" << m << "种资源分别的个数:";
for (int i = 0; i < m; i++)
cin >> Resource[i];
int** Max = new int* [n];
int** Allocation = new int* [n];
int** Need = new int* [n];
int* Available = new int[n];
for (int i = 0; i < n; i++)
{
Max[i] = new int[m];
Allocation[i] = new int[m];
Need[i] = new int[m];
}
cout << "请输入最大需求矩阵 Max(行数:" << n << ",列数:" << m << "):" << endl;
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
cin >> Max[i][j];
cout << "请输入分配矩阵 Allocation(行数:" << n << ",列数:" << m << "):" << endl;
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
cin >> Allocation[i][j];
for (int i = 0; i < n; i++) // Need 矩阵初始化
for (int j = 0; j < m; j++)
Need[i][j] = Max[i][j] - Allocation[i][j];
for (int j = 0; j < m; j++) // Available 矩阵初始化
{
int tol = 0;
for (int i = 0; i < n; i++)
{
tol += Allocation[i][j];
}
Available[j] = Resource[j] - tol;
}
int p_num;
cout << "请输入提出请求的进程号(从 0 开始编号):";
cin >> p_num;
p_num = 1; // 就是这里.
int* Request = new int[m];
cout << "请输入该进程对这" << m << "种资源分别申请的资源数:";
for (int i = 0; i < m; i++)
cin >> Request[i];
/*********************** 输入模块(结束) *********************************/
/*********************** 输出模块一(开始) *******************************/
/*
* 功能:整洁地输出刚刚已经初始化的内容
*/
cout << "初始化后的资源分配图如下:" << endl;
cout << "\t\tMAX\t\tAllocation\tNeed\t\tAvailable" << endl;
cout << "\t";
for (int i = 0; i < 4; i++)
{
cout << "\t";
for (int j = 0; j < m; j++)
{
cout.setf(ios::left);
cout.fill(' ');
cout.width(3);
cout << Res_name[j];
}
}
cout << endl;
for (int i = 0; i < n; i++)
{
cout << "| 进程P" << i << " |\t";
for (int j = 0; j < m; j++)
{
cout.setf(ios::left);
cout.fill(' ');
cout.width(3);
cout << Max[i][j];
}
cout << " |\t";
for (int j = 0; j < m; j++)
{
cout.setf(ios::left);
cout.fill(' ');
cout.width(3);
cout << Allocation[i][j];
}
cout << " |\t";
for (int j = 0; j < m; j++)
{
cout.setf(ios::left);
cout.fill(' ');
cout.width(3);
cout << Need[i][j];
}
cout << " |\t";
for (int j = 0; j < m; j++)
{
cout.setf(ios::left);
cout.fill(' ');
cout.width(3);
if (i == 0)
cout << Available[j];
}
if (i != 0)
cout << "\t |";
else if (i == 0)
cout << "|";
cout << endl;
}
cout << endl;
/*********************** 输出模块一(结束) *******************************/
/************** 银行家算法第二部分:银行家算法模块(开始) ******************/
/*
* [1] Request > Need 则认为出错,因为它所需要的资源数已经超过它所申请的最大值
*/
for (int i = 0; i < m; i++)
{
if (Request[i] > Need[p_num][i])
{
cout << "出错[1]:它所需要的资源数已经超过它所申请的最大值。" << endl;
exit(1);
}
}
/*
* [2] Request > Available 则认为出错,因为它所需要的资源数已经超过它所申请的最大值
*/
for (int i = 0; i < m; i++)
{
if (Request[i] > Available[i])
{
cout << "出错[2]:尚无足够的资源,进程 P" << p_num << " 需等待。" << endl;
exit(1);
}
}
/*
* [3] 系统试探性分配请求的资源给进程
*/
for (int i = 0; i < m; i++)
{
Available[i] = Available[i] - Request[i];
Allocation[p_num][i] = Allocation[p_num][i] + Request[i];
Need[p_num][i] = Need[p_num][i] - Request[i];
}
/************** 银行家算法第二部分:银行家算法模块(结束) ******************/
/*********************** 输出模块二(开始) *******************************/
/*
* 功能: 如果能通过上面 “银行家算法模块”,则整洁地输出一下新的 “资源分配图”(还不是最终的资源分配图)
*/
cout << "加了新的申请后, 新的资源分配图如下:" << endl;
cout << "\t\tMAX\t\tAllocation\tNeed\t\tAvailable" << endl;
cout << "\t";
for (int i = 0; i < 4; i++)
{
cout << "\t";
for (int j = 0; j < m; j++)
{
cout.setf(ios::left);
cout.fill(' ');
cout.width(3);
cout << Res_name[j];
}
}
cout << endl;
for (int i = 0; i < n; i++)
{
cout << "| 进程P" << i << " |\t";
for (int j = 0; j < m; j++)
{
cout.setf(ios::left);
cout.fill(' ');
cout.width(3);
cout << Max[i][j];
}
cout << " |\t";
for (int j = 0; j < m; j++)
{
cout.setf(ios::left);
cout.fill(' ');
cout.width(3);
cout << Allocation[i][j];
}
cout << " |\t";
for (int j = 0; j < m; j++)
{
cout.setf(ios::left);
cout.fill(' ');
cout.width(3);
cout << Need[i][j];
}
cout << " |\t";
for (int j = 0; j < m; j++)
{
cout.setf(ios::left);
cout.fill(' ');
cout.width(3);
if (i == 0)
cout << Available[j];
}
if (i != 0)
cout << "\t |";
else if (i == 0)
cout << "|";
cout << endl;
}
cout << endl;
/*********************** 输出模块二(结束) *******************************/
/************** 银行家算法第二部分:安全性算法模块(开始) ******************/
int* Work = new int[n];
for (int i = 0; i < m; i++)
Work[i] = Available[i];
bool* Finish = new bool[n];
for (int i = 0; i < n; i++)
Finish[i] = false;
int* ans = new int[n]; // 记录序列的编号
for (int i = 0; i < n; i++)
ans[i] = -1;
cout << ">>> 所申请资源未大于其所需资源,亦未大于此时可利用资源,可以预分配并进行安全性检查 <<<" << endl << endl;
/* 执行 DFS + 回溯, 找出符合条件的序列 */
Find_Security_Sequence(n, m, ans, Work, Finish, Need, Allocation); //!!!!!! 全文最核心的函数 !!!!!!!
if (flag == 0)
{
cout << "分配后系统将进入不安全状态,故分配失败。" << endl;
exit(1);
}
/************** 银行家算法第二部分:安全性算法模块(结束) ******************/
/*********************** 输出模块三(开始) *******************************/
/*
* 功能:整洁地输出一下最终的 “资源分配图”
*/
cout << "预分配后系统是安全的,最终实际的资源分配图如下:" << endl;
cout << "\t\tMAX\t\tAllocation\tNeed\t\tAvailable\tFinish" << endl;
cout << "\t";
for (int i = 0; i < 4; i++)
{
cout << "\t";
for (int j = 0; j < m; j++)
{
cout.setf(ios::left);
cout.fill(' ');
cout.width(3);
cout << Res_name[j];
}
}
cout << endl;
for (int ind = 0; ind < n; ind++)
{
int i = ans[ind];
cout << "| 进程P" << i << " |\t";
for (int j = 0; j < m; j++)
{
cout.setf(ios::left);
cout.fill(' ');
cout.width(3);
cout << Max[i][j];
}
cout << " |\t";
for (int j = 0; j < m; j++)
{
cout.setf(ios::left);
cout.fill(' ');
cout.width(3);
cout << Allocation[i][j];
}
cout << " |\t";
for (int j = 0; j < m; j++)
{
cout.setf(ios::left);
cout.fill(' ');
cout.width(3);
cout << Need[i][j];
}
cout << " |\t";
for (int j = 0; j < m; j++)
{
cout.setf(ios::left);
cout.fill(' ');
cout.width(3);
Available[j] += Allocation[i][j];
cout << Available[j];
}
cout << " |\tture\t|";
cout << endl;
}
cout << endl;
cout << "上述资源分配图的安全序列为:";
for (int i = 0; i < n; i++)
{
if (i != n - 1)
cout << "P" << ans[i] << "-->";
else
cout << "P" << ans[i];
}
cout << endl << endl;
cout << "所有的安全序列为:" << endl;
for (int i = 0; i < all_i; i++)
{
for (int j = 0; j < n; j++)
{
if (j != n - 1)
cout << "P" << all_Ans[i][j] << "-->";
else
cout << "P" << all_Ans[i][j];
}
cout << endl;
}
/*********************** 输出模块三(结束) *******************************/
/*********************** 后续处理(开始) *******************************/
delete[] ans;
delete[] Finish;
delete[] Work;
for (int i = 0; i < n; i++)
{
delete[] Max;
delete[] Allocation;
delete[] Need;
}
delete[n] Max;
delete[n] Allocation;
delete[n] Need;
delete[] Available;
delete[] Resource;
delete[] Res_name;
/*********************** 后续处理(结束) *******************************/
return 0;
}
void Print_Brief()
{
cout << "+---------------------------------------------------------------------------------------+" << endl;
cout << "|\t\t>>> 欢迎使用银行家算法 <<< \t\t\t\t\t\t|" << endl;
cout << "|\t 这是一个银行家给多个顾客分发贷款的算法,可以类比到操作系统给进程分配资源。\t|" << endl;
cout << "|\t这时只要把 银行家 换成 操作系统 ,把 顾客 换成 进程 ,把 资金 换成 资源 ,\t|" << endl;
cout << "|\t把银行家决定是否放贷时所用的判断过程(即判断顾客是否有信誉和偿还能力)换成\t|" << endl;
cout << "|\t操作系统决定是否分配资源时所用的判断过程(即判断进程是否能及时归还资源)即可。\t|" << endl;
cout << "+---------------------------------------------------------------------------------------+" << endl;
}
void Find_Security_Sequence(int n, int m, int* ans, int* Work, bool* Finish, int** Need, int** Allocation)
{
int* tmp = new int[n]; // 临时记录答案序列的编号
for (int i = 0; i < n; i++)
{
tmp[i] = -1;
}
Dfs(n, m, 0, tmp, ans, Work, Finish, Need, Allocation);
delete[] tmp;
}
void Dfs(int n, int m, int cnt, int* tmp, int* ans, int* Work, bool* Finish, int** Need, int** Allocation)
{
for (int i = 0; i < n; i++)
{
int step = 3; // 为什么这里要设为 3, 可回见本文前面写的算法设计步骤
if (Finish[i] == 0)
{
for (int j = 0; j < m; j++)
{
if (Need[i][j] > Work[j])
step = 4;
}
}
else // 已经分配过了, 就不用考虑该进程, 直接重复循环
continue;
if (step != 3) // step == 4 时将执行 continue
continue;
else
{
// step == 3 才执行下一步
for (int j = 0; j < m; j++)
Work[j] = Work[j] + Allocation[i][j];
Finish[i] = true; // 设置为 “分配”
tmp[cnt] = i; // 记录临时答案临时
cnt++; // 已分配的进程数 + 1
if (cnt == n) // 如果资源分配完了(即找到一种分配方案),
{
if (flag == 0)
{
for (int j = 0; j < n; j++)
{
ans[j] = tmp[j];
}
}
for (int j = 0; j < n; j++)
{
all_Ans[all_i][j] = tmp[j];
}
all_i++;
flag = 1;
}
else // cnt != n
{
/* 如对代码有疑问, 欢迎咨询 CSDN@一支王同学 */
Dfs(n, m, cnt, tmp, ans, Work, Finish, Need, Allocation);
}
cnt--; // 已分配的进程数 - 1
tmp[cnt] = -999; // 这句话可要可不要
Finish[i] = false; // 重置为 “不分配”
for (int j = 0; j < m; j++)
{
Work[j] = Work[j] - Allocation[i][j];
}
}
}
}
/***** 该代码开源免费,如有疑问欢迎咨询CSDN@一支王同学 *****/