事件驱动的模拟(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、付费专栏及课程。

余额充值