这在里模拟的是一个银行排队系统。该模拟要考虑两类事件:
* 到达事件:这些事件指示新客户到达银行,输入文件指定到达事件发生的时间。这属于外部事件。当客户到达银行时,将发生两件事情之一:若客户到来时出纳员空闲,则客服入队,直接开始办理业务,若出纳员正在办理业务,则新客户必须排在队尾,等候服务。
* 离开事件:这些事件指示客户在办理业务后离开银行。该模拟确定离开事件发生的事件,这属于内部事件(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;
}