銀行排隊模擬(生產者-消費者模擬)
【問題描述】
一個系統模仿另一個系統行為的技術稱為模擬,如飛行模擬器。模擬可以用來進行方案論證、人員培訓和改進服務。計算機技術常用於模擬系統中。
生產者-消費者(Server-Custom)是常見的應用模式,見於銀行、食堂、打印機、醫院、超等提供服務和使用服務的應用中。這類應用的主要問題是消費者如果等待(排隊)時間過長,會引發用戶抱怨,影響服務質量;如果提供服務者(服務窗口)過多,將提高運管商成本。(經濟學中排隊論)
假設某銀行網點有五個服務窗口,分別為三個對私、一個對公和一個外幣窗口。銀行服務的原則是先來先服務。通常對私業務人很多,其它窗口人則較少,可臨時改為對私服務。假設當對私窗口等待服務的客戶(按實際服務窗口)平均排隊人數超過(大於或等於)7人時,等待客戶將可能有抱怨,影響服務質量,此時銀行可臨時將其它窗口中一個或兩個改為對私服務,當客戶少於7人時,將立即恢復原有業務。設計一個程序用來模擬銀行服務。
說明:
1. 增加服務窗口將會增加成本或影響其它業務,因此,以成本增加或影響最小為原則來增加服務窗口,即如果增加一個窗口就能使得按窗口平均等待服務人數小於7人,則只增加一個窗口。一旦按窗口平均等待服務人數小於7人,就減少一個所增加的窗口。
2. 為了簡化問題,假設新到客戶是在每個服務周期開始時到達。
3. 當等待服務人數發生變化時(新客戶到達或有客戶已接受服務),則及時計算按實際服務窗口平均等待服務人數,並按相應策略調整服務窗口數(增加或減少額外的服務窗口,但對私窗口不能減少)。註意:只在獲取新客戶(不管到達新客戶數是否為0)時或已有客戶去接受服務時,才按策略調整服務窗口數。進一步講,增加服務窗口只在有客戶到達的周期內進行(也就是說增加窗口是基於客戶的感受,銀行對增加窗口是不情願的,因為要增加成本,一旦不再有新客戶來,銀行是不會再增加服務窗口的);一旦有客戶去接受服務(即等待客戶減少),銀行將根據策略及時減少服務窗口,因此,在每個周期內,有客戶去接受服務後要馬上判斷是否減少服務窗口(因為能減少成本,銀行是積極的)
本問題中假設對公和對外幣服務窗口在改為對私服務時及服務期間沒有相應因公或外幣服務新客戶到達(即正好空閑),同時要求以增加成本或影響最小為前提,來盡最大可能減少對私服務客戶等待時間。
【輸入形式】
首先輸入一個整數表示時間周期數,然後再依次輸入每個時間周期中因私業務的客戶數。註:一個時間周期指的是銀行處理一筆業務的平均處理時間,可以是一分鐘、三分鐘或其它。例如:
6
2 5 13 11 15 9
說明:表明在6個時間周期內,第1個周期來了2個(序號分別為1,2),第2個來了5人(序號分別為3,4,5,6,7),以此類推。
【輸出形式】
每個客戶等待服務的時間周期數。輸出形式如下:
用戶序號 : 等待周期數
說明:客戶序號與等待周期數之間用符號:分隔,冒號(:)兩邊各有一個空格,等待周期數後直接為回車。
【樣例輸入】
4
2 5 13 11
【樣例輸出】
1 : 0
2 : 0
3 : 0
4 : 0
5 : 0
6 : 1
7 : 1
8 : 0
9 : 1
10 : 1
11 : 1
12 : 1
13 : 2
14 : 2
15 : 2
16 : 3
17 : 3
18 : 3
19 : 4
20 : 4
21 : 3
22 : 4
23 : 4
24 : 4
25 : 5
26 : 5
27 : 5
28 : 6
29 : 6
30 : 6
31 : 7
【樣例說明】
樣例輸入表明有四個時間周期,第一個周期來了2人(序號1-2);第二個周期來了5人(序號3-7);第三個周期來了13人(序號8-20);第四個周期來了11人(序號21-31)。由於第一個時間周期內只來了2人,銀行(有三個服務窗口)能及時提供服務,因此客戶等待時間為0;第二個時間周期內來了5人,銀行一個周期內一次只能服務3人,另有2個在下個周期內服務,因此等待時間為1,其它類推。
【題解】
1 #include<stdio.h> 2 #include<stdlib.h> 3 4 #define MAXSIZE 200 5 #define MINSVR 3 6 #define MAXSVR 5 7 #define NUMBER 7 8 9 typedef struct 10 { 11 int id; 12 int wtime; 13 }CustType; 14 15 CustType queue[MAXSIZE]; 16 int front=0,real=-1,num=0; 17 int Worknum=MINSVR; 18 19 int isEmpty(); 20 int isFull(); 21 void enQueue(CustType q); 22 CustType deQueue(); 23 void updatetime(); 24 void arriveCust(); 25 void service(); 26 27 int main(void) 28 { 29 int clock,sumClock; 30 scanf("%d",&sumClock); 31 clock=1; 32 while(1) 33 { 34 if(!isEmpty()) 35 updatetime(); 36 if(clock<=sumClock) 37 arriveCust(); 38 service(); 39 if(num==0 && clock>sumClock) 40 break; 41 clock++; 42 } 43 return 0; 44 } 45 46 int isEmpty() 47 { 48 return num==0; 49 } 50 int isFull() 51 { 52 return num==MAXSIZE; 53 } 54 void enQueue(CustType q) 55 { 56 57 if(isFull()) 58 exit(-1); 59 else 60 { 61 real=(real+1)%MAXSIZE; 62 queue[real]=q; 63 num++; 64 } 65 return; 66 } 67 CustType deQueue() 68 { 69 CustType q; 70 if(isEmpty()) 71 exit(-1); 72 else 73 { 74 q=queue[front]; 75 front=(front+1)%MAXSIZE; 76 num--; 77 } 78 return q; 79 } 80 void updatetime() 81 { 82 int i; 83 for(i=0;i<num;i++) 84 queue[(front+i)%MAXSIZE].wtime++; 85 return; 86 } 87 void arriveCust() 88 { 89 static int count=1; 90 int i,n; 91 CustType q; 92 scanf("%d",&n); 93 for(i=0;i<n;i++) 94 { 95 q.id=count++; 96 q.wtime=0; 97 enQueue(q); 98 } 99 while((num/Worknum)>=NUMBER && Worknum<MAXSVR) 100 Worknum++; 101 return; 102 } 103 void service() 104 { 105 int i; 106 CustType q; 107 for(i=0;i<Worknum;i++) 108 if(isEmpty()) 109 return; 110 else 111 { 112 q=deQueue(); 113 printf("%d : %d\n",q.id,q.wtime); 114 } 115 while((num/Worknum)<NUMBER && Worknum>MINSVR) 116 Worknum--; 117 return; 118 }
銀行排隊模擬(生產者-消費者模擬)