銀行家演算法:c++實現

來源:互聯網
上載者:User

//任何轉載原始碼的請保留出處作者等相關資訊

//作者:chlaws

//運行環境:visual studio 2008

//描述:銀行家演算法及示範結果

//說明:這裡不給出原創的思路,在閱讀過程中有不懂得可以詢問

#include <iostream><br />#include <cstdlib><br />#include <string><br />#include <iterator><br />#include <algorithm><br />#include <vector><br />#include <cstdlib><br />using namespace std;<br />const int MAX=5;<br />class Banker;<br />class ProcessInfo{<br />public:<br />ProcessInfo()<br />{<br />_processname="";</p><p>memset(_allocation,0,MAX);<br />memset(_need,0,MAX);<br />memset(_work,0,MAX);<br />memset(_tmpalloc,0,MAX);<br />memset(_tmpneed,0,MAX);</p><p>_finish=false;<br />//_insafe=false;<br />}<br />static void Prompt();</p><p>void InitProInfo();<br />ProcessInfo(const ProcessInfo& rhs);<br />ProcessInfo& operator=(const ProcessInfo& rhs);</p><p>~ProcessInfo(){}<br />friend ostream& operator<<(ostream& out,const ProcessInfo& rhs);<br />friend istream& operator>>(istream& in, const ProcessInfo& rhs);<br />friend class Banker;</p><p>private:</p><p>static string _sourcename[MAX];<br />static int _srctype;//資源種類數<br />static int _sourcenum[MAX];//各種資源的數量<br />static int _avaliable[MAX];</p><p>string _processname;<br />int _allocation[MAX];<br />int _need[MAX];<br />static bool _insafe;//判斷是否已進入安全檢查,通過該標誌來確定是否輸出work和max<br />//false 沒進入過,不輸出work,可輸出max<br />//true 已進入過,輸出work,不輸出max<br />int _tmpalloc[MAX];<br />int _tmpneed[MAX];<br />int _work[MAX];<br />bool _finish;<br />};</p><p>//靜態變數定義<br />bool ProcessInfo::_insafe = false;<br />string ProcessInfo::_sourcename[MAX]={"a","b","c"};<br />int ProcessInfo::_srctype=3;<br />int ProcessInfo::_sourcenum[MAX]={10,5,7};<br />int ProcessInfo::_avaliable[MAX]={-1};//第一個數-1用來標識可用資源avariable沒有經過計算<br />//靜態函數定義<br />void ProcessInfo::Prompt()<br />{<br />int tmplen=ProcessInfo::_srctype;<br />int ix;<br />cout << "初始時有" << tmplen << "種資源(";<br />for(ix=0; ix<tmplen-1; ix++)<br />{<br />cout << "[資源名:" << ProcessInfo::_sourcename[ix] <<",數量為:"<br /><< ProcessInfo::_sourcenum[ix] << "],";<br />}<br />cout << "[資源名:" <<ProcessInfo::_sourcename[ix] <<"數量為:"<br /><< ProcessInfo::_sourcenum[ix] << "]" << ")" ;</p><p>//若avariable已經計算過了,則輸出<br />if(ProcessInfo::_avaliable[0] != -1)<br />{<br />cout << ",可用資源分別為(";<br />for(ix=0; ix<tmplen-1; ix++)<br />{<br />cout << ProcessInfo::_avaliable[ix] <<",";<br />}<br />cout << ProcessInfo::_avaliable[ix] << ")";<br />}<br />cout << endl;</p><p>}<br />//重載輸出操作符<br />ostream& operator<<(ostream& out,const ProcessInfo& rhs)<br />{<br />out << rhs._processname << "/t";</p><p>int tmplen=ProcessInfo::_srctype;<br />int max[MAX];<br />int wkalloc[MAX];//work+allocation<br />ostream_iterator<int> itout(out," ");</p><p>//通過是否進入安全檢查來判斷是輸出work還是max<br />if(ProcessInfo::_insafe)<br />{<br />for(int ix=0; ix<tmplen; ix++)<br />{<br />wkalloc[ix]=rhs._work[ix]+rhs._allocation[ix];<br />}<br />copy(rhs._work,rhs._work+tmplen,itout);<br />}<br />else<br />{<br />for(int ix=0; ix<tmplen; ix++)<br />{<br />max[ix]=rhs._allocation[ix]+rhs._need[ix];<br />}<br />copy(max,max+tmplen,itout);<br />}</p><p>out << " ";<br />copy(rhs._allocation,rhs._allocation+tmplen,itout);<br />out << " ";<br />copy(rhs._need,rhs._need+tmplen,itout);<br />out << " ";<br />if(ProcessInfo::_insafe)<br />{<br />copy(wkalloc,wkalloc+tmplen,itout);<br />out << "/t";<br />rhs._finish ? out << "true" : out <<"false";<br />}<br />return out;<br />}<br />//重載輸入操作符<br />istream& operator>>(istream& in, ProcessInfo& rhs)<br />{<br />rhs.InitProInfo();<br />return in;<br />}<br />ProcessInfo& ProcessInfo::operator=(const ProcessInfo& rhs)<br />{<br />_processname=rhs._processname;</p><p>int tmplen=ProcessInfo::_srctype;<br />for(int ix=0; ix<tmplen; ix++)<br />{<br />_allocation[ix]=rhs._allocation[ix];<br />_need[ix]=rhs._need[ix];</p><p>_tmpalloc[ix]=rhs._tmpalloc[ix];<br />_tmpneed[ix]=rhs._tmpneed[ix];<br />_work[ix]=rhs._work[ix];<br />}</p><p>_finish=rhs._finish;<br />_insafe=rhs._insafe;</p><p>return *this;<br />}<br />ProcessInfo::ProcessInfo(const ProcessInfo& rhs)<br />{<br />_processname=rhs._processname;</p><p>int tmplen=ProcessInfo::_srctype;<br />for(int ix=0; ix<tmplen; ix++)<br />{<br />_allocation[ix]=rhs._allocation[ix];<br />_need[ix]=rhs._need[ix];</p><p>_tmpalloc[ix]=rhs._tmpalloc[ix];<br />_tmpneed[ix]=rhs._tmpneed[ix];<br />_work[ix]=rhs._work[ix];<br />}</p><p>_finish=rhs._finish;<br />//_insafe=rhs._insafe;<br />}<br />void ProcessInfo::InitProInfo()<br />{<br />cout << "輸入進程名稱:";<br />cin >> _processname;<br />int tmplen=ProcessInfo::_srctype;<br />int ix;<br />cout << "輸入對每類資源的已指派[allocation](用空格隔開):" ;<br />for(ix=0; ix<tmplen; ix++)<br />{<br />cin >> _allocation[ix];<br />}<br />cout << "輸入對每類資源的需求[need](用空格隔開):";<br />for(ix=0; ix<tmplen; ix++)<br />{<br />cin >> _need[ix];<br />}<br />cout << endl;<br />}</p><p>class Banker{<br />public:<br />Banker()<br />{<br />_ismodify=false;<br />}<br />Banker(const Banker& rhs)<br />{<br />copy(rhs._val.begin(),rhs._val.end(),_val.begin());<br />}<br />void InitBanker();<br />bool SafeCheck();</p><p>int Request(int* request);</p><p>bool BankerCheck(int rindex,int* request);</p><p>friend ostream& operator << (ostream& out,const Banker& rhs);<br />private:<br />//用來重設finish和work變數<br />void reset();<br />bool calavariable();<br />bool modify();</p><p>bool _ismodify;//用來確定是否對初始化資訊做了修改false沒修改,true已修改<br />vector<ProcessInfo> _val;<br />};<br />//Private function define<br />bool Banker::modify()<br />{<br />int tmplen;<br />cout << "輸入資源種類數量:" ;<br />cin >> tmplen;<br />ProcessInfo::_srctype=tmplen;</p><p>cout << "輸入各類資源名稱(用空格隔開):" ;<br />for(int ix=0; ix<tmplen; ix++)<br />{<br />cin >> ProcessInfo::_sourcename[ix];<br />}<br />cout << "輸入各類資源的數量(用空格隔開):";<br />for(int ix=0; ix<tmplen; ix++)<br />{<br />cin >> ProcessInfo::_sourcenum[ix];<br />}<br />return true;<br />}<br />bool Banker::calavariable()//計算每類可用資源數量<br />{<br />int srctypenum=ProcessInfo::_srctype;<br />int processnum=_val.size();<br />int usetotal;<br />for(int id=0; id<srctypenum; id++)<br />{<br />usetotal=0;<br />for(int ix=0; ix<processnum; ix++)<br />{<br />//ProcessInfo::_avaliable[id]+=_val[ix]._allocation[id];<br />usetotal+=_val[ix]._allocation[id];<br />}<br />//ProcessInfo::_avaliable[id] =<br />//ProcessInfo::_sourcenum[id] - ProcessInfo::_avaliable[id];<br />ProcessInfo::_avaliable[id] = ProcessInfo::_sourcenum[id] - usetotal;<br />if(ProcessInfo::_avaliable[id]<0)<br />{<br />//cout << "可用資源數為負";<br />return false;<br />}<br />}<br />return true;<br />}<br />void Banker::reset()<br />{<br />int tmplen=ProcessInfo::_srctype;<br />int processnum=_val.size();<br />for(int ix=0; ix<processnum; ix++)<br />{<br />_val[ix]._finish=false;<br />for(int id=0; id<tmplen; id++)<br />{<br />_val[ix]._work[id]=0;<br />}<br />}<br />}<br />//End private function define</p><p>bool Banker::BankerCheck(int rindex,int* request)<br />{<br />//進入預分配<br />//使用tmpalloc儲存未修改的allocation<br />//使用tmpneed儲存未修改的need<br />//使用臨時變數tmpavaliable儲存未修改的avaliable<br />//修改avaliable,allocation,need<br />int tmplen=ProcessInfo::_srctype;<br />int tmpavaliable[MAX];<br />int ix;<br />for(ix=0; ix<tmplen; ix++)<br />{<br />_val[rindex]._tmpalloc[ix] = _val[rindex]._allocation[ix];<br />_val[rindex]._tmpneed[ix] = _val[rindex]._need[ix];<br />tmpavaliable[ix] = ProcessInfo::_avaliable[ix];<br />ProcessInfo::_avaliable[ix] -= request[ix];<br />_val[rindex]._allocation[ix] += request[ix];<br />_val[rindex]._need[ix] -= request[ix];<br />}<br />//由於初始時調用過安全性檢查,所以要重設finish和work<br />reset();<br />//不存在安全序列,重設avaliable,allocation,need<br />if(!SafeCheck())<br />{<br />for(ix=0; ix<tmplen; ix++)<br />{<br />_val[rindex]._allocation[ix] = _val[rindex]._tmpalloc[ix] ;<br />_val[rindex]._need[ix] = _val[rindex]._tmpneed[ix] ;<br />ProcessInfo::_avaliable[ix] = tmpavaliable[ix] ;<br />}<br />return false;<br />}<br />return true;<br />}<br />void Banker::InitBanker()<br />{<br />char c;<br />ProcessInfo::Prompt();<br />cout << "是否需要修改進程預設的初始相關資訊(y/n):";<br />cin >> c;<br />if (c == 'y' || c == 'Y')<br />{<br />_ismodify=true;<br />if(!modify()){<br />cout << "operator error!";<br />exit(1);<br />}<br />}<br />if(_ismodify)<br />{<br />ProcessInfo::Prompt();<br />}<br />do{<br />ProcessInfo tmpObj;<br />cin >> tmpObj;<br />_val.push_back(tmpObj);<br />//system("cls"); //如果覺得需要重新整理螢幕就把這句加上<br />cout << "是否完成輸入,並進入安全檢查(y/n):";<br />cout.flush();</p><p>cin >> c;<br />}while(c!='y' && c!='Y');</p><p>if(!calavariable())<br />{<br />cout << "calculator avariable error,avariable have negative value!" << endl;<br />exit(1);<br />}<br />}<br />bool Banker::SafeCheck()<br />{<br />int processnum=_val.size();<br />int tmplen=ProcessInfo::_srctype;<br />int tmpwork[MAX]={0};</p><p>copy(ProcessInfo::_avaliable,ProcessInfo::_avaliable+tmplen,tmpwork);<br />bool isnlessw=true;//標識need是否小於work;<br />int safenum=0;//儲存finish為true的次數</p><p>vector<ProcessInfo> safelist;<br />//考慮最壞尋找情況使用processnum次大迴圈進行尋找<br />for(int i=0; i<processnum; i++)<br />{//每次大迴圈中小迴圈,迴圈processnum次<br />for(int ix=0; ix<processnum; ix++)<br />{</p><p>if(_val[ix]._finish == false)<br />{<br />isnlessw=true;<br />//判斷 need <= work;<br />for(int id=0; id<tmplen; id++)<br />{<br />if(_val[ix]._need[id] > tmpwork[id])<br />{<br />isnlessw=false;<br />break;<br />}<br />}<br />if(!isnlessw)//need !<= work,則跳過對finish,work的修改.表示沒有找到合格<br />{<br />continue;<br />}<br />else<br />{<br />_val[ix]._finish=true;<br />safenum += 1;<br />//修改work<br />copy(tmpwork,tmpwork+tmplen,_val[ix]._work);<br />//修改tmpwork<br />for(int id=0; id <tmplen; id++)<br />{<br />//work=work+allocation<br />tmpwork[id]=tmpwork[id]+_val[ix]._allocation[id];<br />}<br />//將符合的要求的進程項插入安全序列中<br />safelist.push_back(_val[ix]);<br />}<br />}<br />}<br />}</p><p>if(safenum != processnum)<br />{<br />cout << "不存在安全序列" << endl;<br />return false;<br />}<br />else<br />{<br />ProcessInfo::_insafe=true;//修改insafe標誌,表示進入了安全檢查.<br />//用於在輸出時輸出work,而不輸出max等<br />cout << "存在安全序列!" <<endl;<br />//ProcessInfo::Prompt();<br />cout << "進程/tWork/tAllocation/tNeed/tWork+Allocation/tFinish/n";<br />ostream_iterator<ProcessInfo> itout(cout,"/n");<br />copy(safelist.begin(),safelist.end(),itout);<br />}<br />return true;<br />}<br />int Banker::Request(int* request)<br />{<br />int tmplen=ProcessInfo::_srctype;<br />//int request[MAX];<br />cout << "輸入請求資源的進程名稱(";<br />int processnum=_val.size();<br />int ix;//用於迴圈中的下標索引變數<br />int rindex=-1;//用來儲存request所對應進程在進程式列中的索引值<br />for(ix=0; ix < processnum-1; ix++)<br />{<br />cout << _val[ix]._processname <<",";<br />}<br />cout << _val[processnum-1]._processname<< "):";<br />string rprocessname;<br />cin >> rprocessname;<br />bool isnametrue=false; //標識輸入的進程名稱是否正確.<br />//int isnametrue=0; //標識輸入的進程名稱是否正確.<br />//判斷進程名是否在進程式列中<br />for(ix=0; ix < processnum; ix++)<br />{<br />if(rprocessname.compare(_val[ix]._processname) == 0)<br />{<br />isnametrue=true;<br />//isnametrue=1;<br />rindex=ix;<br />break;<br />}<br />}<br />if(!isnametrue)<br />{<br />cout<< "輸入的進程名不在進程式列中,出錯退出!" << endl;<br />exit(1);<br />}</p><p>cout << "輸入對各類資源的請求數量(用空格隔開):";<br />for(ix=0; ix<tmplen; ix++)<br />{<br />cin >> request[ix];<br />}</p><p>bool isrlessn=true;//用來標識request是否小於need;<br />//request <= need<br />for(ix=0; ix<tmplen; ix++)<br />{<br />if(request[ix] > _val[rindex]._need[ix])<br />{<br />isrlessn=false;<br />break;<br />}<br />}<br />if(!isrlessn)<br />{<br />cout << "error:request !<= need" << endl;<br />return -1;<br />}</p><p>bool isrlessa=true;//用來標識request是否小於avaliable;<br />//request <= avaliable<br />for(ix=0; ix<tmplen; ix++)<br />{<br />if(request[ix] > ProcessInfo::_avaliable[ix])<br />{<br />isrlessa=false;<br />break;<br />}<br />}<br />if(!isrlessa)<br />{<br />cout << "error:request !<= avaliable" << endl;<br />return -1;<br />}<br />return rindex;<br />}<br />ostream& operator << (ostream& out,const Banker& rhs)<br />{<br />cout << endl;<br />ProcessInfo::Prompt();<br />cout << "進程/tMax/tAllocation/tNeed/n";<br />ostream_iterator<ProcessInfo> itout(out,"/n");<br />copy(rhs._val.begin(),rhs._val.end(),itout);<br />return out;<br />}<br />int main()<br />{<br />Banker b;<br />b.InitBanker();</p><p>cout << b;<br />if(!b.SafeCheck())<br />{<br />cout << "在t0時刻不存在安全序列,結束退出" << endl;<br />exit(1);<br />}<br />else<br />{<br />cout << "所以在t0時刻存在安全序列" << endl;<br />}</p><p>int request[MAX];<br />int rindex;<br />while(1)<br />{<br />rindex=b.Request(request);<br />if(rindex ==-1 )<br />{<br />cout << "請求request 不符合條件" << endl;<br />continue;<br />}<br />if(!b.BankerCheck(rindex,request))<br />{<br />cout << "BankerCheck error:no exist safe queue!" << endl;<br />}<br />}<br /> return 0;<br />}  

 

運行結果如下:

初始時有3種資源([資源名:a,數量為:10],[資源名:b,數量為:5],[資源名:c數量為:7])<br />是否需要修改進程預設的初始相關資訊(y/n):n<br />輸入進程名稱:p0<br />輸入對每類資源的已指派[allocation](用空格隔開):0 1 0<br />輸入對每類資源的需求[need](用空格隔開):7 4 3<br />是否完成輸入,並進入安全檢查(y/n):n<br />輸入進程名稱:p1<br />輸入對每類資源的已指派[allocation](用空格隔開):2 0 0<br />輸入對每類資源的需求[need](用空格隔開):1 2 2<br />是否完成輸入,並進入安全檢查(y/n):n<br />輸入進程名稱:p2<br />輸入對每類資源的已指派[allocation](用空格隔開):3 0 2<br />輸入對每類資源的需求[need](用空格隔開):6 0 0<br />是否完成輸入,並進入安全檢查(y/n):n<br />輸入進程名稱:p3<br />輸入對每類資源的已指派[allocation](用空格隔開):2 1 1<br />輸入對每類資源的需求[need](用空格隔開):0 1 1<br />是否完成輸入,並進入安全檢查(y/n):n<br />輸入進程名稱:p4<br />輸入對每類資源的已指派[allocation](用空格隔開):0 0 2<br />輸入對每類資源的需求[need](用空格隔開):4 3 1<br />是否完成輸入,並進入安全檢查(y/n):y<br />初始時有3種資源([資源名:a,數量為:10],[資源名:b,數量為:5],[資源名:c數量為:7]),可<br />用資源分別為(3,3,2)<br />進程 Max Allocation Need<br />p0 7 5 3 0 1 0 7 4 3<br />p1 3 2 2 2 0 0 1 2 2<br />p2 9 0 2 3 0 2 6 0 0<br />p3 2 2 2 2 1 1 0 1 1<br />p4 4 3 3 0 0 2 4 3 1<br />存在安全序列!<br />進程 Work Allocation Need Work+Allocation Finish<br />p1 3 3 2 2 0 0 1 2 2 5 3 2 true<br />p3 5 3 2 2 1 1 0 1 1 7 4 3 true<br />p4 7 4 3 0 0 2 4 3 1 7 4 5 true<br />p0 7 4 5 0 1 0 7 4 3 7 5 5 true<br />p2 7 5 5 3 0 2 6 0 0 10 5 7 true<br />所以在t0時刻存在安全序列<br />輸入請求資源的進程名稱(p0,p1,p2,p3,p4):p1<br />輸入對各類資源的請求數量(用空格隔開):1 0 2<br />存在安全序列!<br />進程 Work Allocation Need Work+Allocation Finish<br />p1 2 3 0 3 0 2 0 2 0 5 3 2 true<br />p3 5 3 2 2 1 1 0 1 1 7 4 3 true<br />p4 7 4 3 0 0 2 4 3 1 7 4 5 true<br />p0 7 4 5 0 1 0 7 4 3 7 5 5 true<br />p2 7 5 5 3 0 2 6 0 0 10 5 7 true<br />輸入請求資源的進程名稱(p0,p1,p2,p3,p4):p4<br />輸入對各類資源的請求數量(用空格隔開):3 3 0<br />error:request !<= avaliable<br />請求request 不符合條件<br />輸入請求資源的進程名稱(p0,p1,p2,p3,p4):p0<br />輸入對各類資源的請求數量(用空格隔開):0 2 0<br />不存在安全序列<br />BankerCheck error:no exist safe queue!<br />輸入請求資源的進程名稱(p0,p1,p2,p3,p4):p0<br />輸入對各類資源的請求數量(用空格隔開):0 1 0<br />存在安全序列!<br />進程 Work Allocation Need Work+Allocation Finish<br />p1 2 2 0 3 0 2 0 2 0 5 2 2 true<br />p3 5 2 2 2 1 1 0 1 1 7 3 3 true<br />p4 7 3 3 0 0 2 4 3 1 7 3 5 true<br />p0 7 3 5 0 2 0 7 3 3 7 5 5 true<br />p2 7 5 5 3 0 2 6 0 0 10 5 7 true<br />輸入請求資源的進程名稱(p0,p1,p2,p3,p4):22<br />輸入的進程名不在進程式列中,出錯退出!<br />請按任意鍵繼續. . . 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.