离散事件模拟
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 ; //删除失败 }
相关文章推荐
- sdut 2087 离散事件模拟-银行管理
- 离散事件模拟-银行管理
- C语言 离散事件模拟
- 离散事件模拟-银行管理——队列思想(双队列)
- 数据结构学习笔记 --- 队列的应用举例(离散事件模拟)
- 离散事件模拟
- SDUT2087 离散事件模拟-银行管理(模拟)
- c语言版数据结构(奇迹冬瓜)-队列实战(1)离散事件模拟(银行排队)
- 离散事件模拟:循环报数问题(2017年12月CCF第二题)
- 队列->离散事件模拟-银行管理
- 离散事件模拟-银行管理
- 21、数据结构笔记之十九列队实现离散事件模拟
- 队列-模拟离散事件
- 【数据结构】离散事件模拟
- 离散事件模拟-银行管理
- 离散事件模拟-银行管理
- 离散事件模拟-银行管理
- 离散事件模拟(银行业务模拟。实现算法3.6、3.7的程序)
- 22、数据结构笔记之十九列队实现离散事件模拟
- SDUT 2087 离散事件模拟-银行管理(队列模拟)