事件驱动的模拟(event-driven-simulation)在排队中的运用

这在里模拟的是一个银行排队系统。该模拟要考虑两类事件:

* 到达事件:这些事件指示新客户到达银行,输入文件指定到达事件发生的时间。这属于外部事件。当客户到达银行时,将发生两件事情之一:若客户到来时出纳员空闲,则客服入队,直接开始办理业务,若出纳员正在办理业务,则新客户必须排在队尾,等候服务。

* 离开事件:这些事件指示客户在办理业务后离开银行。该模拟确定离开事件发生的事件,这属于内部事件(internal event)当客户完成业务时,随即离开,队列的下一个人(若有)开始办理。

list链表用于存储客户依次到达或者离开的顺序。其项包含到达事件 交易事件及离开时间等信息。queue用于表示当前已达到,正在接受或准备接受服务的客户队列。

异常类:

#ifndef EVENT_EXCEPTION_H_ #define EVENT_EXCEPTION_H_ #include<stdexcept> #include<string> using namespace std; class EventException :public logic_error { public: EventException(const string &message="") :logic_error(message.c_str()) {} }; #endif


表示队列和链表item信息的节点类:

#ifndef EVENT_NODE_H_ #define EVENT_NODE_H_ class EventNode { public: EventNode();//default constructor EventNode(const char &_typ,int _adt,int _tra=0); //constructor bool isArrEvent()const; //detemines whether the event is a arrival event. //if it is return true void setDepEvent(int _det); //if the event is arrival event and //set the event to departure event. int getADtime()const; //get the arrival time or departure time int getTratime()const; private: char type;//event type int adtime;//arrival or departure time int tratime;//if this is a arrival event tra stand for //trasaction time.otherwise set tra=0. }; #endif

#include"event_node.h" #include<iostream> EventNode::EventNode() { type=' '; adtime=tratime=0; } EventNode::EventNode(const char &_typ,int _adt,int _tra) :type(_typ),adtime(_adt),tratime(_tra) { } bool EventNode::isArrEvent()const { return (type=='A'); } void EventNode::setDepEvent(int _det) { type='D'; adtime=_det; tratime=0; } int EventNode::getADtime()const { return adtime; } int EventNode::getTratime()const { return tratime; }


list链表类

#ifndef EVENT_LIST_H_ #define EVENT_LIST_H_ #include"event_node.h" #include"event_exception.h" class EventList { public: EventList(); EventList(const EventList &_list); ~EventList(); //operation functions bool empty()const; int size()const; void insert(const EventNode &_node)throw(EventException); void remove(int _index)throw(EventException); void retrieve(int _index,EventNode &_node) throw(EventException); private: struct LNode { EventNode item; LNode *next; }; LNode *head; int Size; LNode *posite(const EventNode &_node); LNode *find(int _index)throw(EventException); }; #endif

#include<cstddef> #include<cassert> #include"event_list.h" #include<iostream> EventList::EventList() { Size=0; head=NULL; } EventList::EventList(const EventList &_list) { if(_list.head==NULL) { head=NULL; Size=0; } else { LNode *originPtr=_list.head; head=new LNode; assert(head!=NULL); head->item=originPtr->item; LNode *newPtr=head; originPtr=originPtr->next; while(originPtr!=NULL) { newPtr->next= new LNode; assert(newPtr->next!=NULL); newPtr=newPtr->next; newPtr->item=originPtr->item; originPtr=originPtr->next; } newPtr->next=NULL; Size=_list.Size; } } EventList::~EventList() { while(head!=NULL) remove(1); } bool EventList::empty()const { return head==NULL; } int EventList::size()const { return Size; } void EventList::insert(const EventNode &_node)throw(EventException) { LNode *temp=new LNode; if(temp==NULL) throw EventException("EventException :allocate memory failed in insert function !"); else{ temp->item=_node; LNode *pre=posite(_node); if(pre==NULL) { temp->next=head; head=temp; } else{ temp->next=pre->next; pre->next=temp; } Size++; } } void EventList::remove(int _index)throw(EventException) { if(empty()) throw EventException("EventException :remove the items failed in remove function !"); else { try{ Size--; LNode *pre=find(_index-1); if(pre==NULL) { pre=head; head=head->next; pre->next=NULL; delete pre; } else { LNode *cur=pre->next; pre->next=cur->next; cur->next=NULL; delete cur; } }catch(EventException &e) { throw; } } } void EventList::retrieve(int _index,EventNode &_node)throw(EventException) { try{ LNode *cur=find(_index); _node=cur->item; }catch(EventException &e) { throw; } } EventList::LNode *EventList::posite(const EventNode &_node) { LNode *lPtr=NULL; if(empty()) return lPtr; else { LNode *temp=head,*pre; while((temp!=NULL)&& ((temp->item).getADtime()< _node.getADtime())) { pre=temp; temp=temp->next; } if(temp==head) return lPtr; else return pre; } } EventList::LNode *EventList::find(int _index)throw(EventException) { LNode *ptr=NULL; if(_index<0||_index>Size) throw EventException("EventException :index overbounder in find function !"); else if(_index==0) return ptr; else { int i=1; LNode *temp=head; while(i<_index) { temp=temp->next; i++; } return temp; } }


queue队列类:

#ifndef EVENT_QUEUE_H_ #define EVENT_QUEUE_H_ #include"event_exception.h" #include"event_node.h" class EventQueue { public: EventQueue(); EventQueue(const EventQueue &_queue); ~EventQueue(); bool empty()const; int size()const; void push(const EventNode & _node)throw(EventException); void pop()throw(EventException); EventNode &front()throw(EventException); EventNode &back()throw(EventException); private: struct Node { EventNode item; Node *next; }; Node *Front; Node *Back; int Size; }; #endif #include<cstddef> #include<cassert> #include"event_queue.h" EventQueue::EventQueue() { Size=0; Front=Back=NULL; } EventQueue::EventQueue(const EventQueue &_queue) { if(_queue.empty()) { Front=Back=NULL; Size=0; } else { Node *temp=_queue.Front; Front=new Node; assert(Front!=NULL); Front->item=temp->item; Node *newPtr=Front; temp=temp->next; while(temp!= _queue.Back) { newPtr->next=new Node; assert(newPtr->next!=NULL); newPtr=newPtr->next; newPtr->item=temp->item; temp=temp->next; } Back=new Node ; assert(Back!=NULL); Back->item=temp->item; Back->next=NULL; Size=_queue.Size; } } EventQueue::~EventQueue() { while(Front!=NULL) pop(); } bool EventQueue::empty()const { return Size==0; } int EventQueue::size()const { return Size; } void EventQueue::push(const EventNode &_node)throw(EventException) { Node *temp=new Node; if(temp==NULL) throw EventException("EventException :allocate memory failed in push function !"); else{ temp->item=_node; temp->next=NULL; if(empty()) Front=Back=temp; else Back->next=temp; Back=temp; Size++; } } void EventQueue::pop()throw(EventException) { if(empty()) throw EventException("EventException :pop the front item failed in pop function !"); else { Node *temp=Front; if(Front==Back) { Front=Back=NULL; } else Front=Front->next; temp->next=NULL; delete temp; Size--; } } EventNode & EventQueue::front()throw(EventException) { if(empty()) throw EventException("EventException :get front item in queue failed in front function !"); else { return Front->item; } } EventNode & EventQueue::back()throw(EventException) { if(empty()) throw EventException("EventException :get back item in queue in front function !"); else { return Back->item; } }

事件驱动模拟类:

#ifndef EVENT_SIMULATION_H_ #define EVENT_SIMULATION_H_ #include<iostream> #include"event_exception.h" #include"event_list.h" #include"event_queue.h" const int TIME=1000; const int PER=6; class Bank { public: Bank(); void processArrival(EventNode &_node)throw(EventException); void processDeparture(EventNode &_node)throw(EventException); void simulate()throw(EventException); void fillList()throw(EventException); private: EventList bankList; EventQueue bankQueue; int costumNumb; int waittime; }; #endif


#include"bank_simulation.h" #include<ctime> #include<cstdlib> #include<iostream> using namespace std; Bank::Bank() { costumNumb=waittime=0; } void Bank::processArrival(EventNode &_node)throw(EventException) { try{ bool front=bankQueue.empty(); bankQueue.push(_node); bankList.remove(1); if(front) { int deptime= _node.getADtime()+ _node.getTratime(); bankList.insert(EventNode('D',deptime)); } }catch(EventException &e) { throw; } } void Bank::processDeparture(EventNode &_node)throw(EventException) { int curtime=_node.getADtime(); try{ bankQueue.pop(); bankList.remove(1); if(!bankQueue.empty()) { int deptime=curtime+bankQueue.front().getTratime(); int perwait=curtime-bankQueue.front().getADtime(); waittime=waittime+perwait; bankList.insert(EventNode('D',deptime)); } }catch(EventException &e) { throw; } } void Bank::simulate()throw(EventException) { try{ fillList(); costumNumb=bankList.size(); cout<<"event type\ttime\ttransation !"<<endl; while(!bankList.empty()) { EventNode newEvent; bankList.retrieve(1,newEvent); if(newEvent.isArrEvent()) { cout<<"\t"<<'A'<<"\t"<<newEvent.getADtime() <<"\t"<<newEvent.getTratime()<<endl; processArrival(newEvent); } else { cout<<"\t"<<'D'<<"\t"<<newEvent.getADtime() <<endl; processDeparture(newEvent); } } }catch(EventException) { throw; } cout<<"total "<<costumNumb<<" customers served today !"<<endl; cout<<"and waiting total "<<waittime<<" minutes "<<endl; cout<<"each customer average waiting time is "<< waittime*1.0/costumNumb<<" minutes "<<endl; } void Bank::fillList()throw(EventException) { srand(time(0)); int time=0; try{ while(time<TIME) { if(rand()*PER/RAND_MAX<1) { int t=rand()%4+4; bankList.insert(EventNode('A',time,t)); } time++; } }catch(EventException &e) { throw; } }

用于测试的main函数

#include"bank_simulation.h" int main() { Bank abank; try{ abank.simulate(); }catch(EventException &e) { cout<<e.what()<<endl; } return 0; }





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值