离散事件模拟.docx
- 文档编号:8010029
- 上传时间:2023-01-27
- 格式:DOCX
- 页数:18
- 大小:58.49KB
离散事件模拟.docx
《离散事件模拟.docx》由会员分享,可在线阅读,更多相关《离散事件模拟.docx(18页珍藏版)》请在冰豆网上搜索。
离散事件模拟
#include"Queue.h"
#include"shuxu.h"
#defineQu4//离散客户列数
#defineKhjg5//两个相邻的客户的时间间隔的最大值
#defineBlsj30//每个客户办理业务的时间最大值
typedefLinkListEventList;//定义事件链表类型为有序链表
/*typedefstruct
{intArrivalTime;//时间发生时刻
intDuration;//事件类型
}QElemtype;*/
EventListev;//事件表
Eventen;//事件
Eventet;//临时变量
LinkQueueq[Qu];//Qu个客户队列
QElemtypecustomer;//客户记录
intTotalTime=0,CustomerNum=0;//累计客户逗留时间,客户数(初值为0)
intCloseTime;//银行营业时间(单位是分)
intcmp(Eventa,Eventb)
{//依事件a发生时刻<,=或>事件b的时刻分别返回-1,0或1
if(a.OccurTime==b.OccurTime)
return0;
else
return(a.OccurTime-b.OccurTime)/abs(a.OccurTime-b.OccurTime);
}
voidOpenForDay()
{//初始化操作
inti;
InitList(ev);
en.OccurTime=0;//设定第一个客户到达事件
en.NType=Qu;//到达
OrderInsert(ev,en,cmp);//插入事件表
for(i=0;i InitQueue(q[i]); } voidRandom(int&d,int&i) { d=rand()%Blsj+1; i=rand()%Khjg+1; } intMinimum(LinkQueueQ[]) {//返回最短队列的序号 intl[Qu]; inti,j; for(i=0;i l[i]=QueueLength(Q[i]); j=0; for(i=1;i if(l[i] { l[0]=l[i]; j=i; } returnj; } voidCustomerArrived() {//处理客户到达事件 QElemtypef; intdurtime,intertime,i; ++CustomerNum; Random(durtime,intertime);//生成随机数 et.OccurTime=en.OccurTime+intertime;//下个客户到达的时刻 et.NType=Qu;//队列中只有一个客户到达事件 if(et.OccurTime OrderInsert(ev,et,cmp); i=Minimum(q); f.ArrivalTime=en.OccurTime; f.Duration=durtime; EnQueue(q[i],f); if(QueueLength(q[i])==1) { et.OccurTime=en.OccurTime+durtime; et.NType=i; OrderInsert(ev,et,cmp);//设定第i队列的一个离开事件并插入事件表 } } voidCustomerDeparture() {inti; i=en.NType; DeQueue(q[i],customer); TotalTime+=en.OccurTime-customer.ArrivalTime; if(! QueueEmpty(q[i])) {GetHead(q[i],customer); et.OccurTime=en.OccurTime+customer.Duration; et.NType=i; OrderInsert(ev,et,cmp); } } voidBank_Simulation() {Linkp; OpenForDay();//初始化 while(! ListEmpty(ev)) {DelFirst(ev,GetHead(ev),p); en.OccurTime=GetCurElem(p).OccurTime; en.NType=GetCurElem(p).NType; if(en.NType==Qu) CustomerArrived(); else CustomerDeparture(); } printf("顾客总数: %d,所有顾客总共耗时%d分钟,平均每人耗时%d分钟\n",CustomerNum,TotalTime,TotalTime/CustomerNum); } voidmain() { printf("请输入银行营业时间长度单位(单位: 分)\n"); scanf("%d",&CloseTime); Bank_Simulation(); } 附: Queue.h #include #include #include #include #defineTRUE1 #defineFALSE0 #defineOK1 #defineERROR0 #defineINFEASIBLE-1 typedefintstatus; typedefintBoolean; typedefstruct {intArrivalTime;//时间发生时刻 intDuration;//事件类型 }QElemtype; typedefstructQNode//单链队列 {QElemtypedata; QNode*next; }*QueuePtr; structLinkQueue { QueuePtrfront,rear;//对头队尾指针 }; //和栈一样,队列也是操作受限的线性表,只允许在队尾插入元素,在队头删除元素 //为了便于插入元素,设立了队尾指针 statusInitQueue(LinkQueue&Q) {if(! (Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode)))) exit(OVERFLOW); Q.front->next=NULL; returnOK; } statusDestroyQueue(LinkQueue&Q) {while(Q.front) {Q.rear=Q.front->next; free(Q.front); Q.front=Q.rear; } returnOK; } statusClearQueue(LinkQueue&Q) {QueuePtrp,q; Q.rear=Q.front; p=Q.front->next; Q.front->next=NULL; while(p) {q=p; p=p->next; free(q); } returnOK; } statusQueueEmpty(LinkQueueQ) {if(Q.front==Q.rear) returnOK; else returnFALSE; } intQueueLength(LinkQueueQ) { inti=0; QueuePtrp,q; p=Q.front; while(p! =Q.rear) {i++; p=p->next; } returni; } statusGetHead(LinkQueueQ,QElemtype&e)\ {//若队列不空则用e返回Q的队头元素 if(Q.front==Q.rear) returnERROR; else {e=Q.front->next->data;//这里的队头是Q.front->next->data哦 returnOK; } } statusEnQueue(LinkQueue&Q,QElemtypee) {//e入队列是插入队尾哦 QueuePtrp; if(! (p=(QueuePtr)malloc(sizeof(QNode)))) exit(OVERFLOW); p->data=e; p->next=NULL; Q.rear->next=p; Q.rear=p; returnOK; } statusDeQueue(LinkQueue&Q,QElemtype&e) {//出队列,并用e返回其值 QueuePtrp; if(Q.front==Q.rear) returnERROR; p=Q.front->next; e=p->data; Q.front->next=p->next; if(p==Q.rear) Q.rear=Q.front;//找回队尾指针 free(p); returnOK; } statusQueueTraverse(LinkQueueQ,void(*vi)(QElemtype)) {//队头到队尾遍历 QueuePtrp; for(p=Q.front->next;p;p=p->next) vi(p->data); printf("\n"); returnOK; } voidvisit(QElemtypec) { printf("%d",c); } Shuxu.h #include #include #include #include #defineTRUE1 #defineFALSE0 #defineOK1 #defineERROR0 #defineINFEASIBLE-1 typedefintstatus; typedefintBoolean; typedefstruct {intOccurTime;//时间发生时刻 intNType;//时间类型 }Event,Elemtype; typedefstructLNode {Elemtypedata; LNode*next; }*Link,*Position; structLinkList {Linkhead,tail; intlen; }; statusMakeNode(Link&p,Elemtypee) {//分配由p指向的值为e的节点,并返回OK如果分配失败,则返回ERROR p=(Link)malloc(sizeof(LNode)); if(! p) returnERROR; p->data=e; returnOK; } statusFreeNode(Link&p) {free(p); p=NULL; returnOK; } statusInitList(LinkList&L) {Linkp; p=(Link)malloc(sizeof(LNode)); if(p) { p->next=NULL; L.head=L.tail=p; L.len=0; returnOK; } else returnERROR; } statusClearList(LinkList&L) { Linkp,q; if(L.head! =L.tail) { q=p=L.head->next; L.head->next=NULL; while(p! =L.tail){ p=q->next; free(q); q=p; } free(q); L.tail=L.head; L.len=0; } returnOK; } statusDestroyList(LinkList&L) { ClearList(L); FreeNode(L.head); L.tail=NULL; L.len=0; returnOK; } statusInsFirst(LinkList&L,Linkh,Links) {//h指向L的一个节点,把h当做头结点,将s所指的节点插入在第一个节点之前 s->next=h->next; h->next=s; if(h==L.tail) L.tail=h->next; L.len++; returnOK; } statusDelFirst(LinkList&L,Linkh,Link&q) {q=h->next; if(q)//链表非空 { h->next=q->next; if(! h->next); L.tail=h;//补上表尾指针 L.len--; returnOK; } else returnFALSE; } statusAppend(LinkList&L,Links) { //将指针s所指的一串结点链接在线性表L之后,并改变链表L的尾指针向新的尾结点 inti=1; L.tail->next=s; while(s->next) { s=s->next; i++; } L.tail=s; L.len+=i; returnOK; } PositionPriorPos(LinkListL,Linkp) {//已知p指向线性链表的一个结点,返回p所指结点的直接前驱的位置,若无前驱则返回NULL Linkq=L.head->next;; if(q==p) returnNULL; else { while(q->next! =p) q=q->next; returnq; } } statusRemove(LinkList&L,Link&q) {//删除线性链表的表尾结点并以q返回,改变尾指针为新的表尾结点 Linkp=L.head; if(! L.head->next) {q=NULL; returnFALSE; } while(p->next! =L.tail) p=p->next; q=L.tail; p->next=NULL; L.tail=p; L.len--; returnOK; } statusInsBefore(LinkList&L,Link&p,Links) {//已知p指向线性表L中的一个结点,将s所指结点插入p所指结点之前, //并修改指针p指向新插入的结点 Linkq; q=PriorPos(L,p); if(! q) q=L.head; s->next=p; q->next=s; p=s; L.len++; returnOK; } statusInsAfter(LinkList&L,Link&p,Links) {//已知p指向线性表L中的一个结点,将s所指结点插入p所指结点之后, //并修改指针p指向新插入的结点 if(p==L.tail) L.tail=s; s->next=p->next; p->next=s; p=s; L.len++; returnOK; } statusSetCurElem(Linkp,Elemtypee) {//已知p指向线性链表中的一个结点,用e更新p所指结点中数据元素的值 p->data=e; returnOK; } ElemtypeGetCurElem(Linkp) { returnp->data; } statusListEmpty(LinkListL) { if(L.len) returnFALSE; else returnTRUE; } intListLength(LinkListL) { returnL.len; } PositionGetHead(LinkListL){ returnL.head; } PositionGetLast(LinkListL) { returnL.tail; } PositionNextPos(Linkp) { returnp->next; } statusLocatePos(LinkListL,inti,Link&p) {intj; if(i<0||i>L.len) returnERROR; else { p=L.head; for(j=1;j<=i;j++) p=p->next; returnOK; } } PositionLocateElem(LinkListL,Elemtypee,status(*compare)(Elemtype,Elemtype)) {Linkp=L.head; do p=p->next; while(p&&! (compare(p->data,e))); returnp; } statusListTraverse(LinkListL,void(*visit)(Elemtype)) { Linkp=L.head->next; intj; for(j=1;j<=L.len;j++) { visit(p->data); p=p->next; } printf("\n"); returnOK; } statusOrderInsert(LinkList&L,Elemtypee,int(*cmp)(Elemtype,Elemtype)) {//已知L为有序线性表将元素e按照非降序插入在L中 Linko,p,q; q=L.head; p=q->next; while(p! =NULL&&cmp(p->data,e)<0) { q=p; p=p->next; } o=(Link)malloc(sizeof(LNode)); o->data=e; q->next=o; o->next=p; L.len++; if(! p) L.tail=o; returnOK; } statusLocateElem(LinkListL,Elemtypee,Position&q,int(*com)(Elemtype,Elemtype)) {//若升序链表L中存在与E满足判定函数com取值为0的元素则q指示L //中第一个元素的值为e的结点位置,并返回TRUE否则q指示第一个与e满足判断函数 //compare()取值>0的前驱的位置,并返回FALSE Linkp=L.head,pp; do {pp=p; p=p->next; }while(p&&(com(p->data,e)<0)); if(! p||com(p->data,e)>0) {q=pp; returnFALSE; } else { q=p; returnTRUE; } }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 离散 事件 模拟