您的位置:首页 > 其它

离散事件模拟

2014-11-28 00:51 162 查看
#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 ;      //删除失败
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: