/***
* Experiment of DataStructure file
*
* Copyright (c) 2010-2011, htu zhuzhichao. All rights reserved.
*
*Purpose:
* 实现了模拟银行的程序设计,并且包含每一个客户离开时间及统计,以及
* 窗口排队的可视化模拟.运行测试通过.
*
* [Public]
* 2010.10 朱智超 于河师大西区东一楼110宿舍
****/
#define OK 1
#define TRUE 1
#define FALSE 0
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;
//-----------------银行排队模拟
//事件和事件表
typedef struct QCuEvent
{
int OccurTime;
int NType;
struct QCuEvent *next;
}QCuEvent, *EventList;
//窗口前队列元素
typedef struct QCuElem
{
int ArrivalTime;
int Duration;
struct QCuElem *next;
}QCuElem,*QEptr;
//窗口指针
typedef struct {
QEptr front;
QEptr rear;
}QCustomerp,*QCupp;
//主要操作函数
Status OpenForDay(EventList &ev, QCuEvent en, QCupp &q);//开门
Status CustomerArrived(EventList &ev, QCupp &q, QCuEvent en);//顾客到达
Status CustomerDeparture(EventList &ev, QCupp &q, QCuEvent en);//顾客离开
void CloseForDay();
//基本操作函数
Status OrderInser(EventList &ev, QCuEvent en);//按时间顺序插入事件到事件表
int QLength(QCustomerp qn);//求窗口队列长度
int MinCuQueue(QCupp q);//求队最短的窗口
Status DelFirstEvent(EventList &ev);//删除事件表中的第一个事件
Status InitCuQueue(QCustomerp &qn);//初始化窗口队列
Status EnCuQueue(QCustomerp &qn,QEptr Q);//进入队列
Status DeCuQueue(QCustomerp &qn,QCuElem &Q);//删除队列中的元素
Status GetQHead(QCustomerp qn,QCuElem &Q);//获得队列中的第一个元素
Status DestoryQueue(QCustomerp qn);//销毁队列
void Ptint_QStatus(QCustomerp QCu[]);//打印队列长度
void Bank_SimulationFunc();
void test(char str[]);
#include "stdio.h"
#include "stdlib.h"
#include "time.h"
int i=0,e=0,counter=0;
int TotalTime=0,CustomerNum=0; //累计客户逗留时间,客户数
int CloseTime; //关门时间
int windowsnum = 0;
//主函数
void main() {
EventList ev; // 事件表
QCuEvent en;
QCupp QCu = NULL;
OpenForDay(ev, en, QCu);
while (ev->next)
{
en.NType = ev->next->NType;
en.OccurTime = ev->next->OccurTime;
DelFirstEvent(ev);
if (en.NType == 0)
CustomerArrived(ev, QCu, en);
else
CustomerDeparture(ev, QCu, en);
Ptint_QStatus(QCu);
}
CloseForDay();
}
//主要功能子函数
Status OpenForDay(EventList &ev, QCuEvent en, QCupp &q)
{
int temp = 0;
srand((unsigned)time(NULL));
printf("请输入营业时间(单位:分钟):");
scanf("%d",&temp);
CloseTime = temp;
TotalTime = 0;
CustomerNum = 0;
en.OccurTime = 0;
en.NType = 0;
en.next = NULL;
ev = (EventList) malloc(sizeof(QCuEvent));
ev->next = NULL;
OrderInser(ev, en);
printf("请输入办理业务的窗口数(至少1个):");
scanf("%d",&windowsnum);
q = (QCustomerp *) malloc((windowsnum+1)*sizeof(QCustomerp));
for (int i=1;i<=windowsnum;i++)
{
InitCuQueue(q[i]);
}
return OK;
}
Status CustomerArrived(EventList &ev, QCupp &q, QCuEvent en)
{
test("顾客到达处理<<<<<<<<");
CustomerNum ++;
// 产生随机数
//srand(54);
int durtime = rand()%30+1;
int intertime = rand()%5+1;
// 插入到达事件表
QCuEvent enTemp;
int t = en.OccurTime + intertime;
enTemp.OccurTime = t;
enTemp.NType = 0;
enTemp.next = NULL;
if (t < CloseTime) OrderInser(ev, enTemp);
printf("时间%d\n",t);
// 插入最短队
QEptr Q;
Q = (QEptr) malloc(sizeof(QCuElem));
Q->ArrivalTime = en.OccurTime;
Q->Duration = durtime;
Q->next = NULL;
int i = MinCuQueue(q);
EnCuQueue(q[i],Q);
// 插入离开事件
enTemp.OccurTime = en.OccurTime + durtime;
enTemp.NType = i;
enTemp.next = NULL;
if(QLength(q[i]) == 1) OrderInser(ev, enTemp);
return OK;
}
Status CustomerDeparture(EventList &ev, QCupp &q, QCuEvent en)
{
test(">>>>>>>>顾客离开处理");
int i = en.NType;
printf("离开时间%d\n",en.OccurTime);
if(en.OccurTime>CloseTime)
{
DestoryQueue(q[i]);
}
else{
QCuElem customer;
DeCuQueue(q[i],customer);
// 客户逗留时间
TotalTime += en.OccurTime - customer.ArrivalTime;
printf("总时间为%d\n",TotalTime);
if (q[i].front->next)
{
GetQHead(q[i],customer);
QCuEvent enTemp;
enTemp.OccurTime = en.OccurTime + customer.Duration;
enTemp.NType = i;
OrderInser(ev, enTemp);
}
}
return OK;
}
void CloseForDay()
{
printf("***************************************\n");
printf("*\n");
printf("* 所有顾客业务办理总时间:%d分钟\n", TotalTime);
printf("* 业务办理顾客数:%d\n", CustomerNum);
printf("* 平均每人办理时间:%f\n",(float)TotalTime/(float)CustomerNum);
printf("*\n");
printf("***************************************\n");
}
//功能实现子函数
Status OrderInser(EventList &ev, QCuEvent en)
{
EventList entemp,qtemp;
entemp = (EventList) malloc(sizeof(QCuEvent));
entemp->OccurTime = en.OccurTime;
entemp->NType = en.NType;
entemp->next = NULL;
if (!ev->next)
{
ev->next = entemp;
return OK;
}
qtemp = ev;
while(qtemp->next&&qtemp->next->OccurTime < en.OccurTime)
{
qtemp = qtemp->next;
}
entemp->next = qtemp->next;
qtemp->next = entemp;
return OK;
}
int QLength(QCustomerp qn)
{
QEptr qtemp;
int i=0;
qtemp = qn.front->next;
while(qtemp)
{
qtemp = qtemp->next;
i++;
}
return i;
}
int MinCuQueue(QCupp q)
{
int i,min;
for (i=1,min=1;i<=windowsnum;i++)
{
min = QLength(q[min])<=QLength(q[i]) ? min:i;
}
return min;
}
Status DelFirstEvent(EventList &ev)
{
EventList p;
p = ev->next;
ev->next = p->next;
free(p);
return OK;
}
Status InitCuQueue(QCustomerp &qn)
{
qn.front = (QEptr) malloc(sizeof(QCuElem));
qn.front->next = NULL;
qn.rear = qn.front;
return OK;
}
Status EnCuQueue(QCustomerp &qn,QEptr Q)
{
qn.rear->next = Q;
qn.rear = Q;
return OK;
}
Status DeCuQueue(QCustomerp &qn,QCuElem &Q)
{
QEptr qtemp;
qtemp = qn.front->next;
Q.ArrivalTime = qtemp->ArrivalTime;
Q.Duration = qtemp->Duration;
qn.front->next = qtemp->next;
if(qn.rear == qtemp) qn.rear = qn.front;
free(qtemp);
return OK;
}
Status GetQHead(QCustomerp qn,QCuElem &Q)
{
Q.ArrivalTime = qn.front->next->ArrivalTime;
Q.Duration = qn.front->next->Duration;
return OK;
}
Status DestoryQueue(QCustomerp qn)
{
QEptr p;
while(qn.front->next)
{
p = qn.front->next;
qn.front->next = p->next;
free(p);
}
qn.front->next =NULL;
qn.rear = qn.front;
return OK;
}
void Ptint_QStatus(QCustomerp QCu[])
{
int l;
for(int i=1;i<=windowsnum;i++)
{
l = QLength(QCu[i]);
printf("队列%d:长%d:",i,l);
for (int n=1;n<=l;n++)
{
printf("@");
}
printf("\n");
}
}
void test(char str[])
{
printf("--%s--\n",str);
}
评论0