银行家算法C++

"该代码开源免费,如有疑问欢迎咨询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@一支王同学 *****/

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

优化大师傅

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

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

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

打赏作者

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

抵扣说明:

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

余额充值