离散事件模拟
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<conio.h>#define ArriveTime 5 //兩個相鄰客戶到達(dá)銀行的時間間隔不超過5分鐘
#define EventTime 30 //每個客戶辦理業(yè)務(wù)的事件不超過30分鐘
#define ClostTime 100 //關(guān)門時間
#define QueueNum 5 //隊列數(shù),即窗口數(shù)typedef struct {int ArrivalTime ; //到達(dá)時刻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 ; //事件發(fā)生時刻int NType ; //事件類型,0表示到達(dá)事件,1至4表示四個窗口的離開事件
} Event , ElemType; //事件類型,有序表LinkList的數(shù)據(jù)元素類型
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 ;//累計客戶逗留時間和客戶數(shù)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發(fā)生時刻< 或 = 或 > 事件b的發(fā)生時刻分別返回-1或0或1if( a.OccurTime < b.OccurTime )return -1 ;else{if( a.OccurTime == b.OccurTime )return 0 ;elsereturn 1 ;}
}void OpenForDay( )
{int i ;TotalTime = 0 ; CustomerNum = 0 ;InitList( &ev ) ; //初始化事件鏈表為空表en.OccurTime = 0 ; en.NType = 0 ; //設(shè)定第一個客戶到達(dá)事件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( )
{ //處理客戶到達(dá)事件en.NType = 0int durtime , intertime , i ;Event ena ;QElemType qet ;++ CustomerNum ;printf("Customer %d arrived at %d and ", CustomerNum, en.OccurTime);Random( &durtime , &intertime ) ; //生成隨機(jī)數(shù)ena.OccurTime = en.OccurTime + intertime ; //下一客戶到達(dá)時刻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 ) ; //設(shè)定第i個隊列的一個離開事件并插入事件表}
}void CustomerDepture( )
{ //處理客戶離開事件,en.NType > 0int 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 ] )) //設(shè)定第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( ) ;elseCustomerDepture( ) ;}if (++i % 10 == 0){printf( "\n----- 按任意鍵,繼續(xù) -----" ) ;getch( ) ;printf( "\n\n" ) ;}}printf( "The Averge Time is %f.\n" , ( float )TotalTime/CustomerNum ) ;
}int main( )
{Bank_Simulation( ) ;return 0 ;
}//被改造的函數(shù)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 ; //當(dāng)事件鏈表為空時(*L)->next = s ;
}int DelFirst( LinkList *L , LNode h , LNode *p )
{ //已知h指向線性鏈表的頭結(jié)點,刪除鏈表中第一個結(jié)點并以p返回*p = *(h.next) ;if( p ){h.next = (*p).next ;**L = h ;return 1 ; //刪除成功}return 0 ; //刪除失敗
}
總結(jié)
- 上一篇: Apache Commons-loggi
- 下一篇: Eclipse下编写C++程序——CDT