這節(jié)是銀行業(yè)務(wù)模擬程序、
假設(shè)某銀行有4個(gè)窗口對外接待客戶,每個(gè)窗口接待一個(gè)人,當(dāng)有人要辦理業(yè)務(wù)的時(shí)候,如果某窗口空閑,則可辦理,如果不空閑,則排在人最少的后面。現(xiàn)編制一個(gè)程序以模擬銀行這種活動(dòng)并計(jì)算一天中客戶在銀行逗留的平均時(shí)間。
為了計(jì)算這個(gè)平均時(shí)間,要掌握每個(gè)客戶到達(dá)銀行和離開銀行這兩個(gè)時(shí)刻,后者減去前者就是逗留時(shí)間。所有客戶逗留時(shí)間的總和被一天內(nèi)進(jìn)入銀行的客戶數(shù)除便是所求的平均時(shí)間。
下面是銀行業(yè)務(wù)模擬,統(tǒng)計(jì)一天內(nèi)客戶在銀行逗留的平均時(shí)間:
代碼如下:
void Bank_Simulation(int CloseTime){ OpenForDay(); //初始化 while (MoreEvent) { EventDrived(OccurTime, EventType); //事件驅(qū)動(dòng) switch (EventType) { case 'A':CustomerArrived(); break; case 'D':CustomerDeparture();break; default:Invalid(); } } CloseForDay();}下面分析下:1.這個(gè)OpenForDay可以理解成開啟一個(gè)計(jì)時(shí)器,然后最后有CloseForDay()就是關(guān)閉計(jì)時(shí)器。
2.EventDrived(OccurTime,EventType)這個(gè)我們可以看見有個(gè)事件驅(qū)動(dòng),第一個(gè)參數(shù)是當(dāng)前時(shí)間,第二個(gè)參數(shù)是事件類型。
3.這個(gè)事件類型有A,D,和其他,A代表Arrived,D代表Departure,其他事件缺省情況(默認(rèn)情況)是無效的。
算法3.6:
模擬程序中有4個(gè)窗口業(yè)務(wù)窗口,所以要4個(gè)隊(duì)列,對每個(gè)隊(duì)頭客戶都存在一個(gè)將要驅(qū)動(dòng)的客戶離開事件。
因此在任何時(shí)刻即將發(fā)送的事件只有5種可能:
1.新的客戶到達(dá)。
2.1號(hào)窗口客戶離開。
3.2號(hào)窗口客戶離開。
4.3號(hào)窗口客戶離開。
5.4號(hào)窗口客戶離開。
下面是有序鏈表和隊(duì)列的結(jié)構(gòu)體:
typedef struct{ int OccurTime; //事件發(fā)生時(shí)刻 int NType; //事件類型,0表示到達(dá)事件,1-4表示4個(gè)窗口的離開事件}Event,ElemType;typedef LinkList EventList; //事件鏈表類型,定義為有序鏈表typedef struct{ int ArrivalTime; //到達(dá)時(shí)刻 int Duration; //辦理業(yè)務(wù)的時(shí)間}QElemType;由于在實(shí)際的銀行中,客戶到達(dá)的時(shí)刻以及辦理事物所需時(shí)間都是隨機(jī)的,在模擬程序中可用隨機(jī)數(shù)來代替。假設(shè)第一個(gè)顧客進(jìn)門的時(shí)刻為0,即是模擬程序處理的第一個(gè)事件,之后每個(gè)客戶到達(dá)的時(shí)刻在前一個(gè)客戶到達(dá)時(shí)設(shè)定。因此在客戶達(dá)到事件發(fā)生時(shí)需先產(chǎn)生倆個(gè)隨機(jī)數(shù):其一為此時(shí)刻到達(dá)的客戶辦理事物所需時(shí)間durtime;其二為下一客戶到達(dá)時(shí)間間隔imtertime,假設(shè)事件發(fā)生的時(shí)刻為Occurtime,則下一個(gè)客戶到達(dá)的時(shí)刻為Occurtime+intertime。由此應(yīng)產(chǎn)生一個(gè)新的客戶到達(dá)事件插入事件表;剛到達(dá)的客戶則應(yīng)插入到當(dāng)前所含元素最少的隊(duì)列中;若插入前為空,則產(chǎn)生一個(gè)客戶立刻事件插入事件表。客戶離開事件的處理比較簡單。首先計(jì)算該客戶在銀行逗留的時(shí)間,然后從隊(duì)列中刪除該客戶后查看隊(duì)列是否空,若空則設(shè)定一個(gè)新的隊(duì)頭客戶離開事件。
算法如下所示:
// 程序中用到的主要變量EventList ev; // 事件表Event en; // 事件LinkQueue q[5]; // 4個(gè)客戶隊(duì)列,q[0]未用QElemType customer; // 客戶記錄int TotalTime, CustomerNum; // 累計(jì)客戶逗留時(shí)間, 客戶數(shù)int CloseTime;//---------------- 算法 3.7 ------------------int cmp(Event a, Event b) { // 依事件a的發(fā)生時(shí)刻< 或= 或> 事件b的發(fā)生時(shí)刻分別返回-1或0或1 if (a.OccurTime < b.OccurTime) return -1; if (a.OccurTime > b.OccurTime) return +1; return 0;}void Random(int &durtime, int &intertime) { // 生成隨機(jī)數(shù) durtime = random(2, 10); intertime = random(10);}int Minimum(LinkQueue q[]) { // 求長度最短隊(duì)列 int minlen = QueueLength(q[1]); int i = 1; for (int j=2; j<=4; j++) if (QueueLength(q[j]) < minlen) { minlen = QueueLength(q[j]); i = j; } return i;}void OpenForDay() { // 初始化操作 TotalTime = 0; CustomerNum = 0; // 初始化累計(jì)時(shí)間和客戶數(shù)為0 InitList(ev); // 初始化事件鏈表為空表 en.OccurTime = 0; en.NType = 0; // 設(shè)定第一個(gè)客戶到達(dá)事件 OrderInsert(ev, en, cmp); // 按事件發(fā)生時(shí)刻的次序插入事件表 for (int i=1; i<=4; ++i) InitQueue(q[i]); // 置空隊(duì)列} // OpenForDayvoid CustomerArrived() { // 處理客戶到達(dá)事件,en.NType=0 int durtime, intertime, i, t; ++CustomerNum; PRintf("Customer %d arrived at %d and ", CustomerNum, en.OccurTime); Random(durtime, intertime); // 生成隨機(jī)數(shù) t = en.OccurTime + intertime; // 下一客戶到達(dá)時(shí)刻 if (t<CloseTime) // 銀行尚未關(guān)門,插入事件表 OrderInsert(ev, MakeElem(t, 0), cmp); i = Minimum(q); // 求長度最短隊(duì)列 printf("enter the Queue %d/n", i); EnQueue(q[i], MakeQElem(en.OccurTime, durtime)); if (QueueLength(q[i]) == 1) //設(shè)定第i隊(duì)列的一個(gè)離開事件并插入事件表 OrderInsert(ev, MakeElem(en.OccurTime+durtime, i), cmp);} // CustomerArrivedvoid CustomerDeparture() { // 處理客戶離開事件,en.NType>0 printf("Customer departure at %d/n", en.OccurTime); int i = en.NType; DeQueue(q[i], customer); //刪除第i隊(duì)列的排頭客戶 TotalTime += en.OccurTime-customer.ArrivalTime; // 累計(jì)客戶逗留時(shí)間 if (!QueueEmpty(q[i])) { // 設(shè)定第i隊(duì)列的一個(gè)離開事件并插入事件表 GetHead (q[i], customer); OrderInsert(ev, MakeElem(en.OccurTime+customer.Duration, i), cmp); }} // CustomerDeparturevoid Bank_Simulation(int closetime) { int i = 0; BLink p; CloseTime = closetime; printf("Bank_Simulation( %d ) ----- 銀行業(yè)務(wù)模擬/n", closetime); OpenForDay(); // 初始化 while (!ListEmpty(ev)) { printList(ev); if (DelFirst(GetHead(ev), p)) { en = GetCurElem(p); if (en.NType == 0) CustomerArrived(); // 處理客戶到達(dá)事件 else CustomerDeparture(); // 處理客戶離開事件 } if (++i % 9 == 0) { printf("/n----- 按任意鍵,繼續(xù) -----"); getch(); printf("/n/n"); } } // 計(jì)算并輸出平均逗留時(shí)間 printf("/nThe Average Time is %f/n", (float)TotalTime/CustomerNum);} // Bank_Simulation
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注