银行业务模拟(计算客户平均等待时间)
definition.h
==============================================
#define CLOSETIME 1440
typedef struct{
unsigned OccurTime, NType;//事件发生时刻;事件类型,6代表到达事件,0-5代表6个窗口的
离开事件
}Event;//链表数据元素类型
typedef struct{
Event event;
struct Enode *next;
}Enode, *EventList;
typedef struct{
unsigned ArrTime, Duration;//到达时刻;办理时间
}QElem;//队列数据元素类型
typedef struct{
QElem Cust;//客户记录
struct Qnode *next;
}Qnode, *Qptr;
typedef struct{
Qptr front, rear;//队头指针,队尾指针
}LinkQueue;
EventList ev;//事件表
Event en;//事件
LinkQueue q[6];//6个客户队列
QElem customer;//客户记录
unsigned TotalTime, CustNum;//累计客户逗留时间,客户数
int Open();//初始化操作
int CustArr();//处理客户到达事件
EventList InitList();//创建链表
int OrderInsert(EventList, Event);//插入事件表
int InitQueue(LinkQueue *);//建立空队列
short Minimun();//求长度最短队列
unsigned QueueLength(LinkQueue);//计算队列长度
int EnQueue(LinkQueue *, QElem);//进入队列
int CustDepart();//处理客户离开事件
int DeQueue(LinkQueue *);//出队
void DelFirst();//删除事件表第一个节点,并把值赋给en
==========================================================================
main.c
============================================================
#include <stdio.h>
#include "definition.h"
int main()
{
if( !Open() )
return 1;//初始化失败,退出
while(ev->next){
DelFirst();//删除事件表第一个节点,并把值赋给en
if( en.NType == 6 ){
if( !CustArr() )
return 1;
}
else{
if( !CustDepart() )
return 1;
}
}
printf( "平均逗留时间为:%g\n", (float)TotalTime / CustNum );
return 0;
}
//还没回收动态分配了的空间,懒得写了
=====================================================================
function.c
=====================================================
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <time.h>
#include "definition.h"
int Open()//初始化操作
{
short i;
srand(time (NULL));//生成随机数种子
CustNum=TotalTime=0;//初始化累计时间和客户数
if( !(ev=InitList()) )//初始化事件链表
return 0;//创建失败,返回0
en.OccurTime=0;
en.NType=6;//设定第一个客户到达事件
if( !OrderInsert(ev, en) )//插入事件表
return 0;//插入失败,返回0
for(i=0; i<6; i++){//置空队列
if( !InitQueue(&q[i]) )
return 0;//创建队列失败,返回0
}
return 1;
}
int CustArr()//处理客户到达事件,en.NType==6
{
unsigned durtime, intertime;
QElem e;
short i;
CustNum++;
//生成随机数
durtime = rand() % 30 + 1;//事务处理时间不超过30分钟
intertime = rand() % 5 + 1;//5分钟内有一位客人到达银行
e.ArrTime=en.OccurTime;
e.Duration=durtime;
en.OccurTime += intertime;//下一客户到达时间
if(en.OccurTime < CLOSETIME){//银行尚未关门,插入事件表
if( !OrderInsert(ev, en) )//插入失败
return 0;
}
i=Minimun();//求长度最短队列
if( !EnQueue(&q[i], e) )
return 0;
if( QueueLength(q[i]) == 1 ){//设定第i队列的一个离开事件并插入事件表
en.NType=i;
en.OccurTime=e.ArrTime+durtime;
OrderInsert(ev, en);
}
return 1;
}
int CustDepart()//处理客户离开事件,en.NType==(0 — 5)
{
Qptr tmp;
unsigned i = en.NType;
if( !DeQueue( &q[i] ) )//删除排头客户
return 0;
TotalTime = TotalTime + en.OccurTime - customer.ArrTime;//累计逗留时间
if( q[i].front != q[i].rear ){
tmp = q[i].front->next;
customer = tmp->Cust;
en.OccurTime += customer.Duration;
if( !OrderInsert(ev, en) )
return 0;
}
return 1;
}
int DeQueue(LinkQueue *Q)//出队
{
Qptr tmp;
if(Q->front==Q->rear)
return 0;//如果队列已空,返回0
tmp=Q->front->next;
customer=tmp->Cust;
Q->front->next=tmp->next;
if(Q->rear==tmp)//如果队尾元素被删除,则队尾指针要指向头结点
Q->rear=Q->front;
free(tmp);
return 1;
}
int EnQueue(LinkQueue *Q, QElem e)//进入队列
{
Qptr tmp;
tmp=(Qptr)malloc(sizeof(Qnode));
if(!tmp)
return 0;//进栈失败,返回0
tmp->Cust=e;
tmp->next=NULL;
Q->rear->next=tmp;
Q->rear=tmp;
return 1;
}
short Minimun()//求长度最短队列
{
unsigned h=0, i, j, k;
j=QueueLength(q[0]);
for(i=1; i<6; i++){
k = QueueLength(q[i]);
if( j > k ){
j = k;
h = i;
}
}
return h;
}
unsigned QueueLength(LinkQueue Q)//计算队列长度
{
unsigned i;
for(i=0; Q.front->next; i++)
Q.front=Q.front->next;
return i;
}
EventList InitList()//创建链表
{
EventList h;
if( !( h=(EventList)malloc(sizeof(Enode)) ) )//创建失败,返回0
return 0;
h->next=NULL;
return h;
}
int OrderInsert(EventList ev, Event a)//插入事件表
{
EventList tmp, h=ev, e=ev->next;
if( !(tmp=InitList()) )//分配空间失败,返回0
return 0;
//插入
tmp->event=a;
while( e && (a.OccurTime > e->event.OccurTime) ){
h=e;
e=e->next;
}
h->next=tmp;
tmp->next=e;
return 1;
}
int InitQueue(LinkQueue *Q)//建立空队列
{
Q->rear=Q->front=(Qptr)malloc(sizeof(Qnode));
if(!Q->front)//创建失败,返回0
return 0;
Q->front->next=NULL;
return 1;
}
void DelFirst()//删除事件表第一个节点,并把值赋给en
{
EventList tmp = ev->next;
ev->next = tmp->next;
en = tmp->event;
free(tmp);
}