#include<stdio.h>
#include<malloc.h>
#include<time.h>
#include<stdlib.h>
#define WINDOWS 10 //定义窗口数
typedef struct _Event//事件结构体
{
struct _Event *next;
int OccurTime;//事件发生时刻
int NType;//事件类型(0表示客户到来,其他表示客户离开)
}EventType,*EventList;
typedef struct _Elem//窗口队列中的元素结构体
{
struct _Elem *next;
int ArrivalTime;//客户到达时刻
int Duration;//客户办理业务需要的时间
}ElemType,*ElemList;
typedef struct
{
ElemList front;
ElemList rear;
}pElem;//队列的头指针和尾指针
int CustomerNum;//总的客户数
int TotalTime;//总的处理时间
int CloseTime;//关门时间
void InitEventList(EventList *head)//事件链表初始化(可能是多余的,我觉得^_^)
{
(*head)->next=NULL;
}
void InitElemList(pElem *ptr)//窗口队列初始化
{
ElemType *p=(ElemType *)malloc(sizeof(ElemType));
p->next=NULL;
ptr->front=ptr->rear=p;
}
void EnterEvList(EventList *head,EventType en)//事件链表的插入操作
{
EventType *tmp1=(*head)->next,*tmp2=(*head);//tmp2是tmp1的前驱
EventType *tmp=(EventList)malloc(sizeof(EventType));
tmp->NType=en.NType;
tmp->OccurTime=en.OccurTime;
tmp->next=NULL;
while(tmp1)
{
if(tmp1->OccurTime>tmp->OccurTime)
{
tmp2->next=tmp;
tmp->next=tmp1;
return;
}
else
{
tmp1=tmp1->next;
tmp2=tmp2->next;
}
}
if(!tmp1)
{
tmp2->next=tmp;
}
}
void Push(pElem *ptr,ElemType custo)//队列的入队操作
{
ElemType *tmp=(ElemType *)malloc(sizeof(ElemType));
tmp->ArrivalTime=custo.ArrivalTime;
tmp->Duration=custo.Duration;
tmp->next=NULL;
ptr->rear->next=tmp;
ptr->rear=tmp;
}
void DeEvList(EventList *head,EventType *p)//链表的删除操作
{
EventType *tmp;
if(NULL==(*head)->next)
{
printf("The List is Empty\n");
return;
}
p->NType=(*head)->next->NType;
p->OccurTime=(*head)->next->OccurTime;
tmp=(*head)->next;
(*head)->next=(*head)->next->next;
free(tmp);
}
void GetHeadQU(pElem *ptr,ElemType *p)//取队列的头结点
{
p->ArrivalTime=ptr->front->next->ArrivalTime;
p->Duration=ptr->front->next->Duration;
}
void Pop(pElem *ptr,ElemType *p)//队列的出队操作
{
ElemType *tmp;
if(ptr->front==ptr->rear)
{
printf("The Queue is Empty\n");
return;
}
p->ArrivalTime=ptr->front->next->ArrivalTime;
p->Duration=ptr->front->next->Duration;
tmp=ptr->front->next;
ptr->front->next=ptr->front->next->next;
if(NULL==ptr->front->next)
{
ptr->rear=ptr->front;
}
}
int Length_LIST(EventList *head)//取链表的长度
{
EventType *p=(*head)->next;
int i=0;
while(p)
{
i++;
p=p->next;
}
return i;
}
int Length_QU(pElem*ptr)//取队列的长度
{
ElemType *p=ptr->front->next;
int i=0;
while(p)
{
i++;
p=p->next;
}
return i;
}
int Minimum(pElem **ptr)//求最短的队列
{
int i,tmp2=1;
int tmp=Length_QU(ptr[1]);
for(i=2;i<=WINDOWS;i++)
{
if(tmp>Length_QU(ptr[i]))
{
tmp2=i;
tmp=Length_QU(ptr[i]);
}
}
return tmp2;
}
int EmptyList(EventList *head)//判断链表是否为空
{
if(NULL==(*head)->next)
return 1;
else
return NULL;
}
int EmptyQU(pElem *ptr)//判断队列是否为空
{
if(ptr->front==ptr->rear)
return 1;
else
return NULL;
}
void Random(int *durtime,int *intertime)//产生随机数
{
srand(time(NULL));
*durtime=rand()%10+5;
*intertime=rand()%4+1;
}
void OpenForDay(EventList *head,pElem **ptr)
{
EventType en;
TotalTime=0;
CustomerNum=0;
InitEventList(head);
en.NType=0;
en.OccurTime=0;
EnterEvList(head,en);
for(int i=1;i<=WINDOWS;i++)
{
InitElemList(ptr[i]);
}
}
void CustomerArrived(EventType en,EventList *head,pElem **ptr)
{
int durtime,intertime,t,i;
EventType tmp;
ElemType tmp1;
++CustomerNum;
Random(&durtime,&intertime);
t=en.OccurTime+intertime;
printf("客户到达 到达时间为 %d\n",en.OccurTime);
tmp.NType=0;
tmp.OccurTime=t;
if(t<CloseTime)
EnterEvList(head,tmp);
i=Minimum(ptr);
tmp1.ArrivalTime=en.OccurTime;
tmp1.Duration=durtime;
Push(ptr[i],tmp1);
if(Length_QU(ptr[i])==1)
{
tmp.NType=i;
tmp.OccurTime=en.OccurTime+durtime;
EnterEvList(head,tmp);
}
}
void CustomerDeparture(EventType en,EventList *head,pElem **ptr)
{
int i;
ElemType p;
EventType tmp;
i=en.NType;
Pop(ptr[i],&p);
TotalTime+=(en.OccurTime-p.ArrivalTime);
printf("客户离开 所在的窗口为 %d,到达时间是 %d,离开时间是 %d\n",i,p.ArrivalTime,en.OccurTime);
if(!EmptyQU(ptr[i]))
{
GetHeadQU(ptr[i],&p);
tmp.NType=i;
tmp.OccurTime=p.Duration+en.OccurTime;
EnterEvList(head,tmp);
}
}
void Bank_Simulation(int CloseTime,EventList *head,pElem **ptr)
{
OpenForDay(head,ptr);
EventType tmp;
while(!EmptyList(head))
{
DeEvList(head,&tmp);
if(tmp.NType==0)
CustomerArrived(tmp,head,ptr);
else
CustomerDeparture(tmp,head,ptr);
}
printf("总处理时间%d\n",TotalTime);
printf("总的客户数%d\n",CustomerNum);
printf("The Average Time is %f\n",(float)TotalTime/CustomerNum);
}
int main()
{
pElem *ptr[WINDOWS+1];
EventType *tmp=(EventType*)malloc(sizeof(EventType));
tmp->next=NULL;
EventList *head=&tmp;
printf("Please input the close time(minutes):");
scanf("%d",&CloseTime);
for(int i=1;i<=WINDOWS;i++)
{
ptr[i]=(pElem*)malloc(sizeof(pElem));
}
Bank_Simulation(CloseTime,head,ptr);
return 0;
}