⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 simulation.h

📁 用C++实现银行的模拟
💻 H
字号:
#include<iostream.h>
#include"PQueue.h"
#include"RandomNumber.h"
typedef Event DataType;
class Simulation
{
private:
	struct Tellerstats
{
	int finishService;//该窗口何时空闲
	int totalCustomerCount;//服务顾客数
	int totalCustomerWait;//顾客等待时间总计
	int totalService;//服务时间总计
};
	int SimulationLength;// 模拟的时间长度(以分钟计)
	int numTellers;//出纳窗口个数
	int nextCustomer;//下一位客户的编号
	int arrivalLow,arrivalHigh;//下一位客户到达的时间范围
	int serviceLow,serviceHigh;//服务时间段
	Tellerstats tstat [11];// 窗口记录数组(最多10个窗口)
	PQueue pq;// 保存事件的优先级队列
	RandomNumber rnd;// 随机变量(到达和服务的时间)
	//RunSimulation用到的私有函数
	int NextArrivalTime();// 随机产生下一个客户到达的时间
	int GetServiceTime();// 随机产生服务时间
	int NextAvailableTeller();// 确定下一个可用的出纳窗口
public:
	Simulation();// 构造函数
	void RunSimulation();// 执行模拟
	void PrintSimulationResults();//输出结果 
};
Simulation::Simulation(void)
{
	int i;
	Event firstevent;
	//初始化窗口信息参数
	for(i=1;i<=10;i++)
	{
		tstat[i].finishService=0;
		tstat[i].totalService=0;
		tstat[i].totalCustomerWait=0;
		tstat[i].totalCustomerCount=0;
	}
	nextCustomer=1;
	//读入用户输入的模拟条件
	cout<<"Enter the Simulation time in minutes:";
	cin>>SimulationLength;
	cout<<endl;
	cout<<"Enter the number of bank tellers:";
	cin>>numTellers;
	cout<<endl;
	cout<<"Enter the range of arrival times in minutes:";
	cin>>arrivalLow>>arrivalHigh;
	cout<<endl;
	cout<<"Enter the range of service times in minutes:";
	cin>>serviceLow>>serviceHigh;
	cout<<endl;
	//产生第一个到达事件,它不需要窗口号,等待时间和服务时间
	//pq.PQInsert(Event(0,arrival,1,0,0,0));
}
//决定下一个到达事件的时间
int Simulation::NextArrivalTime(void)
{
	return arrivalLow+rnd.Random(arrivalHigh-arrivalLow+1);
}
//决定客户服务时间
int Simulation::GetServiceTime(void)
{
	return serviceLow+rnd.Random(serviceHigh-serviceLow+1);
}
//返回第一个空闲窗口
int Simulation:: NextAvailableTeller(void)
{
	//开始时假定所有窗口在关门时都结束服务
	int minfinish=SimulationLength;
	//给在关门之前到达但服务时间超出关门时间的顾客随机分配一个窗口
	int minfinishindex=rnd.Random(numTellers)+1;
	//找到最先空闲的窗口
	for(int i=1;i<=numTellers;i++)
		if(tstat[i].finishService<minfinish)
		{
			minfinish=tstat[i].finishService;
			minfinishindex=i;
		}
		return minfinishindex;
}
//计算银行的总客户人数和所有客户的总等待时间
void Simulation::PrintSimulationResults(void)
{
	int cumCustomers,CumWait;
	float avgCustWait,tellerwork,tellerWorkPercent;
	for(int i=1;i<=numTellers;i++)
	{
		cumCustomers+=tstat[i].totalCustomerCount;
		CumWait+=tstat[i].totalCustomerWait;
	}
    //给出客户平均等待时间和每一个出纳窗口办理业务的时间百分比
	cout<<endl;
	cout<<"********Simulation Summary********"<<endl;// 打印标题
	cout<<"Simulation of"<<SimulationLength<<"minutes"<<endl;// 打印模拟时间长度
	cout<<"No.of customers:"<<cumCustomers<<endl;// 打印客户总数
	cout<<"Average Customer Wait:";
	avgCustWait=float(CumWait)/cumCustomers+0.5;// 计算平均等待时间
	cout<<avgCustWait<<"minutes"<<endl;// 打印平均等待时间
    //cout<<"Average Customer wait:"<<avgCustWait<<"minutes"<<endl;
	for(i=1;i<=numTellers;i++)// 打印各个出纳窗口信息
	{
		cout<<" Teller # "<<i<<"% Working:";// 窗口号码
		//显示最接近的百分数
		tellerwork=float (tstat[i].totalService)/SimulationLength;// 窗口平均服务时间
		tellerWorkPercent=tellerwork*100.0+0.5;// 服务时间百分比
		cout<<tellerWorkPercent<<endl;
	}
}
void Simulation::RunSimulation(void)
{
	Event e,newevent;
	//返回该事件的时间,加上窗口的超时
 	SimulationLength=(e.Gettime()<=SimulationLength)?SimulationLength:e.Gettime();
	//计算下一到达时间
    int	nexttime=e.Gettime()+NextArrivalTime();
	if(nexttime>SimulationLength);
		//处理已有事件,但不再产生新事件
		//continue;
	else
	{
		//为下一顾客产生到达事件并放入队列中nextCustomer++
		newevent=Event(nexttime,arrival,nextCustomer,0,0,0);
		pq.PQInsert(newevent);
	}
	//顾客所需服务时间
	int servicetime=GetServiceTime();
	//提供此次服务的窗口
	int tellerID=NextAvailableTeller();
	//若窗口空闲,置其finishService域为当前时间
	if (tstat[tellerID].finishService==0)
		tstat[tellerID].finishService=e.Gettime();
	//计算顾客等待时间
    int	waittime=tstat[tellerID].finishService-e.Gettime();
	//修改窗口的统计数据
	tstat[tellerID].totalCustomerWait+=waittime;
	tstat[tellerID].totalCustomerCount++;
	tstat[tellerID].totalService+=servicetime;
	tstat[tellerID].finishService+=servicetime;
	newevent=Event(tstat[tellerID].finishService,departure,e.GetCustomerID(),tellerID,waittime,servicetime);
	pq.PQInsert(newevent);
	tellerID=e.GetTellerID();
	//若该窗口无人等待,则将其置为空闲
	if(e.Gettime()==tstat[tellerID].finishService)
		tstat[tellerID].finishService=0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -