离散事件模拟

来源:互联网 发布:mac照片怎么删除 编辑:程序博客网 时间:2024/05/17 04:53
#include<stdio.h>#include<stdlib.h>#include<time.h>#include<conio.h>#define ArriveTime 5   //两个相邻客户到达银行的时间间隔不超过5分钟#define EventTime  30   //每个客户办理业务的事件不超过30分钟#define ClostTime  100   //关门时间#define QueueNum   5   //队列数,即窗口数typedef struct { int ArrivalTime ;   //到达时刻 int Duration ;    //办理事物所需时间} QElemType;typedef struct QNode           { QElemType data; struct QNode *next;} QNode, *QueuePtr;typedef struct                   { QueuePtr front;            //队头指针 QueuePtr rear;             //队尾指针} LinkQueue;void InitQueue(LinkQueue *Q) ;void EnQueue(LinkQueue *Q, QElemType e) ;int QueueLength(LinkQueue Q) ;void DeQueue(LinkQueue *Q, QElemType *e) ;int QueueEmpty(LinkQueue Q) ;void GetHead(LinkQueue Q,QElemType *e) ;//--------------------------------------------------------//typedef struct { int OccurTime ;    //事件发生时刻 int NType ;     //事件类型,0表示到达事件,1至4表示四个窗口的离开事件} Event , ElemType;    //事件类型,有序表LinkList的数据元素类型typedef struct LNode{ ElemType data; struct LNode *next;}LNode,*LinkList;typedef LinkList EventList ; //事件链表类型,定义为有序链表void InitList(LinkList *L) ;void OrderInsert(LinkList *L,ElemType e , int (*cmp)(ElemType a , ElemType b )) ; //按序插入int ListEmpty( LinkList L ) ;LNode GetHeadL( LinkList L ) ;int DelFirst( LinkList *L , LNode h , LNode *p ) ;ElemType GetCurElem( LNode p ) ;//--------------------------------------------------------////--------程序中用到的主要变量--------------//EventList ev ;    //事件表Event  en ;    //事件LinkQueue q[ QueueNum ] ;  //4个客户队列QElemType customer ;   //客户记录int   TotalTime , CustomerNum ;//累计客户逗留时间和客户数int cmp( Event a , Event b ) ;void OpenForDay( ) ;void Random( int *durtime , int *intertime ) ;int Minimun( LinkQueue q[ ] ) ;void CustomerArrived( ) ;void CustomerDepture( ) ;void Bank_Simulation( ) ;//---------------------------------------------------------//#include "head.h"int cmp( Event a , Event b ){ //依事件a发生时刻< 或 = 或 > 事件b的发生时刻分别返回-1或0或1 if( a.OccurTime < b.OccurTime )  return -1 ; else {  if( a.OccurTime == b.OccurTime )   return 0 ;  else   return 1 ; }}void OpenForDay( ){ int i ; TotalTime = 0 ; CustomerNum = 0 ; InitList( &ev ) ;       //初始化事件链表为空表 en.OccurTime = 0 ; en.NType = 0 ;   //设定第一个客户到达事件 OrderInsert( &ev , en , cmp ) ;    //插入事件表.OrderInsert:按序插入 for( i = 1 ; i < QueueNum ; ++ i )  InitQueue( &q[ i ] ) ;}void Random( int *durtime , int *intertime ){ srand( (unsigned)time( NULL ) ); (*durtime) = rand( )%EventTime + 1  ;// srand( (unsigned)time( NULL ) ); (*intertime) = rand( )%ArriveTime + 1 ;}int Minimun( LinkQueue q[ ]  ){ int i , len , minque = 0 , min = 100 ; for( i = 1 ; i < QueueNum ; ++ i ) {  len = QueueLength( q[ i ] ) ;  if( len < min )  {   min = len ;   minque = i ;  } } return minque ;}void CustomerArrived( ){ //处理客户到达事件en.NType = 0 int durtime , intertime , i ; Event ena ; QElemType qet ; ++ CustomerNum ; printf("Customer %d arrived at %d and ", CustomerNum, en.OccurTime); Random( &durtime , &intertime ) ;    //生成随机数 ena.OccurTime = en.OccurTime + intertime ;  //下一客户到达时刻 ena.NType = 0 ; if( ena.OccurTime < ClostTime )  OrderInsert( &ev , ena , cmp ) ; i = Minimun( q ) ;        //求长度最短队列 qet.ArrivalTime = en.OccurTime ; qet.Duration = durtime ; EnQueue( &q[ i ] , qet ) ;  if( QueueLength( q[ i ] ) == 1 ) {   ena.OccurTime = en.OccurTime + durtime ;  ena.NType = i ;  OrderInsert( &ev , ena , cmp ) ;   //设定第i个队列的一个离开事件并插入事件表 }}void CustomerDepture( ){ //处理客户离开事件,en.NType > 0 int i ; QElemType customer ; ElemType ena ; printf("Customer departure at %d\n", en.OccurTime) ; i = en.NType ; DeQueue( &q[ i ], &customer ) ;     //删除第i队列的排头客户 TotalTime += en.OccurTime - customer.ArrivalTime ;//累计客户逗留时间 if( !QueueEmpty( q[ i ] ))      //设定第i队列的一个离开事件并非插入事件表 {  GetHead( q[ i ] , &customer ) ;  ena.OccurTime = en.OccurTime + customer.Duration ;  ena.NType = i ;  OrderInsert( &ev , ena , cmp ) ; }}void Bank_Simulation( ){ LNode p ; int i = 0 ; OpenForDay( ) ; while( !ListEmpty( ev ) ) {  if( DelFirst( &ev , GetHeadL( ev ) , &p ) )  {   en = GetCurElem( p ) ;   if( 0 == en.NType )    CustomerArrived( ) ;   else    CustomerDepture( ) ;  }  if (++i % 10 == 0)  {   printf( "\n----- 按任意键,继续 -----" ) ;   getch( ) ;   printf( "\n\n" ) ;  } } printf( "The Averge Time is %f.\n" , ( float )TotalTime/CustomerNum ) ;}int main( ){ Bank_Simulation( ) ; return 0 ;}//被改造的函数void OrderInsert(LinkList *L,ElemType e , int (*cmp)(ElemType a , ElemType b )) //按序插入{ LinkList s , p , q ; s = (LinkList)malloc(sizeof(LNode)); s->data = e;  q = (*L) ;         p = q->next ; while( p ) {  if( cmp( p->data , e ) > 0 )  {   s->next = q->next;                     q->next = s;   return ;  }  q = p ;  p = p->next ; } s->next = (*L)->next ;     //当事件链表为空时 (*L)->next = s ;} int DelFirst( LinkList *L , LNode h , LNode *p ){ //已知h指向线性链表的头结点,删除链表中第一个结点并以p返回 *p = *(h.next) ; if( p ) {  h.next = (*p).next ;  **L = h ;  return 1 ;     //删除成功 } return 0 ;      //删除失败}

0 0
原创粉丝点击