需要添加:一个客户从某窗口离开,有其他窗口的比该窗口的人数多2,那么从其他窗口队列中,有一个客户从队尾离开,排到该窗口。(希望详细一些)
//main.cpp
#include"simulation.h"
int main()
{
Simulation S;
S.RunSimulation();
S.PrintSimulationResults();
return 0;
}
//simulation.h
#ifndef Simulation_H
#define Simulation_H
#include"pqueue.h" //优先级队列类模板
#include"queue.h" //队列类模板
#include<conio.h>
#include<iostream.h>
#include <stdlib.h>
#include <iomanip.h>
class Event //事件类型
{
int time; //事件发生时间
int etype; //事件类型:0表示到达,1、2、3、4……表示从几号窗口离开
public:
Event():time(0),etype(0){}
Event(int t,int e):time(t),etype(e){}
operator int()const{return(time);}
int GetTime()const{return(time);}
int GetEventType()const{return(etype);}
};
struct Service //排队客户信息结构
{
int arrivalTime;
int serviceTime;
};
struct TellerStats //窗口信息结构
{
int totalCustomer;
int totalService;
int totalWait;
};
class Simulation
{
int SimulationLength; //模拟时间长度
int numTellers; //服务窗口个数
int arrivalLow; //客户到达的最短间隔
int arrivalHigh; //客户到达的最长间隔
int serviceLow; //客户最短的服务时间
int serviceHigh; //客户最长的服务时间
TellerStats t[11]; //最多是个窗口,TellerStats t[1]~TellerStats t[10]
Queue<Service>Q[11];
PQueue<Event>PQ;
int GetIntertime()
{return(arrivalLow+rand()%(arrivalHigh-arrivalLow+1));}
int GetServiceTime()
{return(serviceLow+rand()%(serviceHigh-serviceLow+1));}
int GetNextTeller();//(1)选择人少的排队
void Arrived(const Event&e);
void Daparture(const Event&e);
void PrintPQueue();
void PrintQueue();
public:
Simulation();
Simulation(int L,int nT,int aL,int aH,int sL,int sH);
void RunSimulation();
void PrintSimulationResults();
};
Simulation::Simulation() //模拟过程的初始化
{
cout<<"input the simulation time in minutes:";
cin>>SimulationLength;
cout<<"input the number of tellers(2-10):";
cin>>numTellers;
cout<<"input the range of arrival times in minutes:";
cin>>arrivalLow>>arrivalHigh;
cout<<"input the range of service times in minutes:";
cin>>serviceLow>>serviceHigh;
for(int i=1;i<=numTellers;i++)
{
t[i].totalCustomer=0;
t[i].totalService=0;
t[i].totalWait=0;
}
PQ.Push(Event(0,0));
}
Simulation::Simulation(int L,int nT,int aL,int aH,int sL,int sH)
{
SimulationLength=L;
numTellers=nT;
arrivalLow=aL;
arrivalHigh=aH;
serviceLow=sL;
serviceHigh=sH;
for(int i=1;i<=numTellers;++i)
{
t[i].totalCustomer=0;
t[i].totalService=0;
t[i].totalWait=0;
}
PQ.Push(Event(0,0));
}
int Simulation::GetNextTeller()//(1)选择人少的排队
{
int i,size=Q[1].size(),min=1;
for(i=2;i<=numTellers;i++)
if(Q[i].size()<size)
{
size=Q[i].size();
min=i;
}
return min;
}
void Simulation::Arrived(const Event&e)
{
Service s;
int next,i;
s.arrivalTime=e.GetTime();
s.serviceTime=GetServiceTime();
i=GetNextTeller();
Q[i].Push(s);
if(Q[i].size()==1)
PQ.Push(Event(s.arrivalTime+s.serviceTime,i));
next=e.GetTime()+GetIntertime();
if(next<SimulationLength)
PQ.Push(Event(next,0));
cout<<"ServiceTime NextTeller next\n";
cout<<setw(5)<<s.serviceTime;
cout<<setw(12)<<i;
cout<<setw(8)<<next<<endl;
}
void Simulation::Daparture(const Event&e)
{
int i=e.GetEventType();
Service s=Q[i].Pop();
t[i].totalCustomer++;
t[i].totalService+=s.serviceTime;
t[i].totalWait+=e.GetTime()-s.arrivalTime;
if(!Q[i].Empty())
{
s=Q[i].Front();
PQ.Push(Event(e.GetTime()+s.serviceTime,i));
}
}
void Simulation::PrintPQueue()
{
int n=PQ.Size();
int i=0;
Event e,*p=new Event[n];
cout<<"*****EventQueue*****\n";
while(!PQ.Empty())
{
e=PQ.Pop();
cout<<'('<<e.GetTime()<<" "<<e.GetEventType()<<')';
p[i++]=e;
}
for(i=0;i<n;++i)
PQ.Push(p[i]);
cout<<endl;
delete[]p;
}
void Simulation::PrintQueue() //显示窗口队列
{
int n;
Service s;
cout<<"*****Tellers*****\n";
for(int t=1;t<=numTellers;t++)
{
cout<<t<<":";
n=Q[t].size();
for(int i=1;i<=n;i++)
{
s=Q[t].Pop();
cout<<'('<<s.arrivalTime<<" "<<s.serviceTime<<')';
Q[t].Push(s);
}
cout<<endl;
}
}
void Simulation::RunSimulation() //执行模拟
{
Event e;
PrintPQueue();
PrintQueue();
cout<<endl;
getch();
while(!PQ.Empty())
{
e=PQ.Pop();
if(e.GetEventType()==0)
{
Arrived(e);
PrintPQueue();
PrintQueue();
cout<<endl;
}
else
{
Daparture(e);
PrintPQueue();
PrintQueue();
cout<<endl;
}
getch();
}
}
void Simulation::PrintSimulationResults() //显示模拟结果
{
int i,totalCustomers=0,totalWait=0;
for(i=1;i<=numTellers;i++)
{
totalCustomers+=t[i].totalCustomer;
totalWait+=t[i].totalWait;
}
cout<<totalCustomers<<endl;
cout<<totalWait<<endl;
}
#endif