1 //离散事件模拟,模拟银行营业排队情况 2 #include <stdio.h> 3 #include <time.h> 4 #include <stdlib.h> 5 6 #define OK 1 7 #define ERROR 0 8 #define TRUE 1 9 #define FALSE 0 10 11 typedef int Status; 12 13 typedef struct Event{ //事件类型 14 int OccurTime; //事件发生时刻 15 int NType; //事件类型,0表示到达事件,1-4表示4个窗口离开事件 16 struct Event *next; 17 }Event,*ElemType; 18 19 typedef struct{ //链表类型 20 ElemType head; 21 ElemType tail; 22 int len; 23 }LinkList; 24 25 typedef LinkList EventList; //事件链表 26 27 typedef struct QElem{ //队列元素 28 int ArrveTime; //到达时间 29 int Duration; //办理事务所需事件 30 struct QElem *next; 31 }QElem,*QElemType; 32 33 typedef struct{ //队列类型 34 QElemType head; 35 QElemType tail; 36 }LinkQueue; 37 38 Status InitList(LinkList *L); //初始化事件链表 39 Status OrderInsert(LinkList *L, Event e); //将事件e按时间顺序插入有序链表L中 40 Status ListEmpty(LinkList *L); //判断链表为空,为空返回TRUE 41 Status DelFirst(LinkList *L,ElemType e); //删除链表首结点,用e返回 42 Status ListTraverse(LinkList *L); //遍历链表 43 44 Status InitQueue(LinkQueue *Q); //初始化队列 45 Status EmptyQueue(LinkQueue *Q); //判断队列为空 46 Status DelQueue(LinkQueue *Q, QElemType e); 47 Status EnQueue(LinkQueue *Q, QElem e); //接点e插入队列 48 int QueueLength(LinkQueue Q); 49 Status GetHead(LinkQueue *Q, QElemType e); //取队列首部结点e 50 Status QueueTraverse(LinkQueue *Q); 51 52 Event NewEvent(int occurTime, int nType); //创建新事件 53 54 int Min(int a[], int n); //返回长度为n的数组a[]第一个最小下标,从1开始 55 int ShortestQueue(); //获取最短队列编号 56 void OpenForDay(); //初始化操作 57 void CustomerArriver(); //顾客到达事件 58 void CustomerDeparture(); //顾客离开事件 59 void Bank_Simulation(); //银行排队模拟 60 void PrintEventList(); //输出事件列表 61 void PrintQueue(); //打印当前队列 62 63 EventList ev; 64 Event en; 65 LinkQueue q[5]; 66 QElem customer; 67 int TotalTime, CustomerNum; 68 int CloseTime = 50; 69 70 //----------------------main()--------------------// 71 int main() 72 { 73 Bank_Simulation(); 74 return 0; 75 } 76 77 //-----------------------模拟排队----------------// 78 void OpenForDay() 79 { 80 int i; 81 TotalTime = 0; 82 CustomerNum = 0; 83 InitList(&ev); 84 en.OccurTime = 0; 85 en.NType = 0; 86 OrderInsert(&ev, en); 87 for (i = 1; i < 5; i++) 88 InitQueue(&q[i]); 89 } 90 91 void CustomerArrived() 92 { 93 int durtime, intertime, i, t; 94 QElem e; 95 ++CustomerNum; 96 intertime = rand() % 5 + 1; 97 durtime = rand() % 30 + 1; 98 t = en.OccurTime + intertime; 99 if (t < CloseTime) 100 { 101 printf("A new customer will arrive at:%d\n", t); 102 OrderInsert(&ev, NewEvent(t, 0)); 103 i = ShortestQueue(); 104 e.ArrveTime = en.OccurTime; 105 e.Duration = durtime; 106 EnQueue(&q[i], e); 107 if (QueueLength(q[i]) == 1) 108 OrderInsert(&ev, NewEvent(en.OccurTime + durtime, i)); 109 } 110 } 111 112 void CustomerDeparture() 113 { 114 int i = en.NType; 115 DelQueue(&q[i], &customer); 116 printf("A customer leaves at:%d\n", en.OccurTime); 117 TotalTime += en.OccurTime - customer.ArrveTime; 118 if (!EmptyQueue(&q[i])) 119 { 120 GetHead(&q[i], &customer); 121 OrderInsert(&ev, NewEvent(en.OccurTime + customer.Duration, i)); 122 } 123 } 124 125 void Bank_Simulation() 126 { 127 OpenForDay(); 128 srand((unsigned)time(NULL)); 129 while(!ListEmpty(&ev)) { 130 DelFirst(&ev, &en); 131 if (en.NType == 0) 132 CustomerArrived(); 133 else 134 CustomerDeparture(); 135 PrintQueue(); 136 } 137 printf("\nTotal time is:%d min,average time is: %g min.\n",TotalTime, 138 (float)TotalTime/CustomerNum); 139 } 140 141 void PrintQueue() 142 { 143 int i; 144 for ( i = 1; i < 5; i ++) 145 { 146 printf("Queue %d have %d customer(s):", i, QueueLength(q[i])); 147 QueueTraverse(&q[i]); 148 } 149 printf("\n"); 150 } 151 152 void PrintEventList() 153 { 154 printf("Current Eventlist is:\n"); 155 ListTraverse(&ev); 156 } 157 158 int Min(int a[], int n) 159 { 160 int i, tmp, ind = 0; 161 tmp = a[0]; 162 for (i = 1; i < n; i ++) 163 if (a[i] < tmp) 164 { 165 tmp = a[i]; 166 ind = i; 167 } 168 return ind; 169 } 170 171 int ShortestQueue() 172 { 173 int i, a[4]; 174 for(i = 1; i <= 4; i++) 175 a[i-1] = QueueLength(q[i]); 176 return Min(a, 4) + 1; 177 } 178 179 //------------------------队和栈表操作-------------------// 180 Event NewEvent(int occurT, int nType) 181 { 182 Event e; 183 e.OccurTime = occurT; 184 e.NType = nType; 185 return e; 186 } 187 188 Status InitList(LinkList *L) 189 { 190 L->head = L->tail = (ElemType)malloc(sizeof(Event)); 191 if (!L->head) 192 { 193 printf("Apply for memory error.LinkList initializefailed.\n"); 194 exit(0); 195 } 196 197 L->head->next = NULL; 198 return OK; 199 } 200 201 Status OrderInsert(LinkList *L, Event e) 202 { 203 ElemType p, q, newptr; 204 newptr = (ElemType)malloc(sizeof(Event)); 205 if(!newptr) 206 { 207 printf("Apply for memory error.\n"); 208 exit(0); 209 } 210 *newptr = e; 211 if (TRUE == ListEmpty(L)) 212 { 213 L->head->next = newptr; 214 L->tail = newptr; 215 L->tail->next = NULL; 216 return OK; 217 } 218 q = L->head; 219 p = L->head->next; 220 while(p) 221 { 222 if (p->OccurTime >= newptr->OccurTime) 223 break; 224 q = p; 225 p = p->next; 226 } 227 q->next = newptr; 228 newptr->next = p; 229 if (!p) 230 L->tail = newptr; 231 return OK; 232 } 233 234 Status ListEmpty(LinkList *L) 235 { 236 if((L->head == L->tail) && (L->head != NULL)) 237 return TRUE; 238 else 239 return FALSE; 240 } 241 242 Status DelFirst(LinkList *L, ElemType e) 243 { 244 ElemType p = L->head->next; 245 if (!p) 246 return ERROR; 247 L->head->next = p->next; 248 *e = *p; 249 free(p); 250 if (L->head->next == NULL) 251 L->tail = L->head; 252 return OK; 253 } 254 255 Status ListTraverse(LinkList *L) 256 { 257 ElemType p = L->head->next; 258 if (!p) 259 { 260 printf("List is empty.\n"); 261 return ERROR; 262 } 263 while (p) 264 { 265 printf("OccurTime:%d, Event Type:%d\n", p->OccurTime, p->NType); 266 p = p->next; 267 } 268 printf("\n"); 269 return OK; 270 } 271 272 Status InitQueue(LinkQueue *Q) 273 { 274 Q->head = Q->tail = (QElemType)malloc(sizeof(QElem)); 275 if (!Q->head) 276 { 277 printf("Apply for memory error.LinkQueue initialize failed.\n"); 278 exit(0); 279 } 280 Q->head->next = NULL; 281 return OK; 282 } 283 284 Status EmptyQueue(LinkQueue *Q) 285 { 286 if ((Q->head == Q->tail) && (Q->head != NULL)) 287 return TRUE; 288 else 289 return FALSE; 290 } 291 292 Status DelQueue(LinkQueue *Q, QElemType e) 293 { 294 QElemType p = Q->head->next; 295 if (!p) 296 return ERROR; 297 *e = *p; 298 Q->head->next = p->next; 299 free(p); 300 if (!Q->head->next) 301 Q->tail = Q->head; 302 return OK; 303 } 304 305 Status EnQueue(LinkQueue *Q, QElem e) 306 { 307 QElemType p = (QElemType)malloc(sizeof(QElem)); 308 if (!p) 309 { 310 printf("Apply for memory error, new element can't enqueue.\n"); 311 exit(0); 312 } 313 *p = e; 314 p->next = NULL; 315 Q->tail->next = p; 316 Q->tail = p; 317 return OK; 318 } 319 320 int QueueLength(LinkQueue Q) 321 { 322 int count = 0; 323 QElemType p = Q.head->next; 324 while(p) 325 { 326 count ++; 327 p = p->next; 328 } 329 return count; 330 } 331 332 Status GetHead(LinkQueue *Q, QElemType e) 333 { 334 if (EmptyQueue(Q)) 335 return ERROR; 336 e = Q->head->next; 337 return OK; 338 } 339 340 Status QueueTraverse(LinkQueue *Q) 341 { 342 QElemType p = Q->head->next; 343 if(!p){ 344 printf("--Is empty.\n"); 345 return ERROR; 346 } 347 while(p){ 348 printf("(%d,%d) ",p->ArrveTime,p->Duration); 349 p = p->next; 350 } 351 printf("\n"); 352 return OK; 353 }