数据结构 大作业1:模拟银行
写在前面
此为数据结构大作业,相较之前几届任务有所变动,故将报告上传供学弟学妹们参考。
作业为ddl前紧急赶制完成,加上本人水平有限,可能出现错误,欢迎批评指正。
(生成顾客时用random出现仅有一类顾客的情况,故直接按奇偶数分类顾客TT)
一、实验完成情况
1.VIP窗口
vip客户和普通客户都能在对应柜台进行服务。
2.VIP插队权限
vip顾客能实现插队
3.VIP等待时限
vip顾客在等待后能插队
4.一般客户等待时限
两类顾客均能插队
二、主要代码介绍
1.VIP窗口
此部分包含普通柜台和VIP柜台的处理逻辑。
在que.h文件中实现了顾客结构体和队伍。
代码主要包括三个核心类:teller
(柜台类)、monitor
(监控类)和alarm
(报警类),以及一个用于初始化客户的辅助函数和主函数。
顾客结构体
顾客结构体主要包括顾客的相关信息。
struct customer
{
int num;//
int Type;//是否为vip
int arrivetime;//到达时间
int startserve;//开始服务的时间
int leavetime;//离开时
customer* next;//指向下一个的指针
};//顾客结构体
队列
用队列的保存在等待的顾客。包含了入队和出队方法和判空方法
class queue
{
private:
customer* start;//队首
customer* end;//队尾
int count;//队列长度
public:
queue(void);
void add(customer* newcust);//用户入队
customer* leave();//队首离队
int isempty();
};
柜台类teller
单个柜台类,实现服务顾客的功能,包含服务顾客,查询柜台状态等方法。
class teller//单个柜台
{
private:
int number;
int isEmpty;//0空闲,1有人
int serviceHigh;
int serviceLow;
RandomNumber rnd;
public:
int time;//服务停止时间时间
customer* servenow;//正在服务的顾客的对象
teller();
int type;// 0-普通 1-vip
void init(int num, int servHigh, int servLow, int atype, RandomNumber ran);//初始化柜台号和服务最长最短时间
int empty();//查询柜台是否为空
void arriveacustomer(int arrtime);//有客户到达设置离开时间
void free(int time);//客户离开释放柜台
int leavetime();//查询空闲的时间
void flashleavetime(int nexttime);//在无客户时刷新下一个服务时间。
};
monitor
monitor
主要作为所有柜台的管理,用于查询下一个空闲柜台。
class monitor//仅用于管理柜台
{
private:
teller* Tellers;
int numTeller;
public:
monitor(teller* tellers, int num)
{
Tellers = tellers;
numTeller = num;
}
int checktime();//检查下一个可服务时间,返回柜台号
};
alarm
alarm
用于管理下一个需要处理的事件。银行模拟中主要需要处理的事件为,有顾客到达银行和有顾客离开。刷新方法将下一个待处理的时间设置为到达事件和离开时间中较为紧急的一个。
class alarm//设置时间
{
public:
int nextTeller;
int nextArriveTime;
int nextLeaveTime;
int nextResponce;//下一个待处理的时间
int nextType;// -1 无, 0 顾客到达 ,1 顾客离开
alarm(void);
void setnext();//刷新
};
initCustomer
对顾客进行初始化。并输出客户到达信息。
主函数
维护了普通顾客和vip顾客两个队列。
首先读入信息,对各个类初始化。生成第一个顾客并放入队列,柜台响应,将顾客放入对应柜台。
而后开始进行模拟,根据alarm
中得信息得知需处理得事件是什么,如果为顾客到达,则将顾客放入对应队列并生成下一个顾客到达时间,设置alarm
中的时间;如果是顾客离开,则首先将柜台清空(如柜台不为空),从对应队列中取一个顾客,如队列为空,则下一个顾客离开响应时间设置为有顾客到达。而后刷新alarm
将时间赋值为下一个响应时间。到达模拟时长后,对于剩余的队伍中的顾客服务完,此时的顾客生成时间设置为MAX_TIME
。
2.VIP插队权限
插队实现在上一版代码的基础上实现。
顾客结构体
顾客结构体中添加信息insert
,用于区分顾客是否是插队过的,便于找到第一个未插队的顾客并在其前面实现插队。
队列
队列类中,增加一个pirnt
和insert
方法,用于实现队列打印和插队
在此问题中,顾客未加入队列直接插入队首。
void queue::insert(customer* newcust)//实现插队
{
cout<<"customer "<<newcust->num<<"(VIP) insert."<<endl<<"Befor insert:";
print();
newcust->insert = 1;
customer* tmp = start;
if (start == NULL)//队列为空直接加入队列
add(newcust);
else
{
if (tmp->insert == 0)
{
newcust->next = tmp;
start = newcust;
}
else
{
while (tmp->next)
{
if (tmp->next->insert == 0)
break;
tmp = tmp->next;
}
newcust->next = tmp->next;
tmp->next = newcust;
}
}
cout<<"After insert:";
print();
}
主函数
主函数中,两个队列可合并为一个队列,在有顾客到来时,如果为vip顾客则将其直接插入队首,否则添加至队尾,其余部分基本无变化。
3.VIP等待时限
等待时限在上一版代码的基础上实现。
顾客结构体
顾客结构体中添加等待时限信息,普通顾客的等待时限此时置为MAX_TIME
,如时间到达wait
则需进行插队。
队列
对插队功能进行修改,需要先将顾客从顾客中取出而后才能进行插入。
添加查找下一个vip顾客的功能,主要用于查找下一个可能到达等待时限的顾客。
alarm
添加待响应时间insert
。刷新功能进行修改。
class alarm//设置时间
{
public:
int nextTeller;
int nextArriveTime;
int nextLeaveTime;
int nextInsertTIme;//需要插队的时间
customer* needInsert;//可能需要插队的顾客
int nextResponce;//下一个待处理的时间
int nextType;// -1 无, 0 顾客到达 ,1 顾客离开 ,2 需要插队
alarm(void);
void setnext();//刷新
};
主函数
对于此问题的主要改动在于添加插队待处理时间,和alarm
的nextInsertTIme
,needInsert
的控制。
在有顾客到来时,如果目前队列中没有要插队顾客即needInsert
为空,则将needInsert
设置为该顾客并同步修改时间。
在有顾客离开时,如果从队列中取出的顾客是needInsert
,则查找队列中的下一个VIP顾客并将needInsert
设置为该顾客。
在有顾客需要插队时,调用插队功能并查找队列中的下一个VIP顾客并将needInsert
设置为该顾客。
4.一般客户等待时限
队列
在队列中添加查找下一普通顾客的方法。
alarm
添加两个可能需要插队的顾客成员。
class alarm//设置时间
{
public:
int nextTeller;
int nextArriveTime;
int nextLeaveTime;
int nextInsertTime;//需要插队的时间
customer* needInsertVip;//可能需要插队的顾客
customer* needInsertNormal;
int nextResponce;//下一个待处理的时间
int nextType;// -1 无, 0 顾客到达 ,1 顾客离开 ,2 需要插队
alarm(void);
void setnext();//刷新
};
主函数
主要改动在于插入时对普通客户中需要插队的和vip的插队的时间进行比较,在刷新alarm
时也要对两类时间进行比较。
while (time <= simulationLength)
{
if (aAlarm.nextType == 0)//到达一个客户
{
customer* newCustomer = new customer;
initCustomer(newCustomer, time, customercount, maxWaitVip,maxWaitNormal, rnd);
normalQueue.add(newCustomer);
normalQueue.print();
if (aAlarm.needInsertVip == NULL && newCustomer->Type == 1)//目前未有闹钟客户
aAlarm.needInsertVip = newCustomer;
if (aAlarm.needInsertNormal == NULL && newCustomer->Type == 0)
aAlarm.needInsertNormal = newCustomer;
customercount += 1;
aAlarm.nextArriveTime = rndNext(rnd, arrivalLow, arrivalHigh, time);
}
else if (aAlarm.nextType == 1) //一个客户离开
{
if (tellers[aAlarm.nextTeller].servenow != NULL)//柜台不为空
tellers[aAlarm.nextTeller].free(time);
if (!normalQueue.isempty()) {
customer* cus = normalQueue.leave(); // 从普通队列中取出顾客
if (cus == aAlarm.needInsertVip)
aAlarm.needInsertVip = normalQueue.nextVIP(cus);
if (cus == aAlarm.needInsertNormal)
aAlarm.needInsertNormal = normalQueue.nextNormal(cus);
tellers[aAlarm.nextTeller].servenow = cus;
tellers[aAlarm.nextTeller].arriveacustomer(time);
}
else//队列为空
{
tellers[aAlarm.nextTeller].flashleavetime(aAlarm.nextArriveTime);
}
//设置下一个响应时间和柜台
aAlarm.nextTeller = tellermonitor.checktime();
aAlarm.nextLeaveTime = tellers[aAlarm.nextTeller].leavetime();
}
else if (aAlarm.nextType == 2)//有一个顾客要插队。
{
if (aAlarm.needInsertNormal != NULL || aAlarm.needInsertVip != NULL)
{
if (aAlarm.needInsertNormal == NULL)
{
cout << "Time " << time << ": customer " << aAlarm.needInsertVip->num << "(VIP) wait " << maxWaitVip << " ! INSERT!" << endl;
customer* tmp = normalQueue.nextVIP(aAlarm.needInsertVip);//插队的下一个客户即为需要关注的插队对象
normalQueue.insert(aAlarm.needInsertVip);//插队
aAlarm.needInsertVip = tmp;
}
else if (aAlarm.needInsertVip == NULL)
{
cout << "Time " << time << ": customer " << aAlarm.needInsertNormal->num << " wait " << maxWaitNormal << " ! INSERT!" << endl;
customer* tmp = normalQueue.nextNormal(aAlarm.needInsertNormal);//插队的下一个客户即为需要关注的插队对象
normalQueue.insert(aAlarm.needInsertNormal);//插队
aAlarm.needInsertNormal = tmp;
}
else if (aAlarm.needInsertNormal->wait < aAlarm.needInsertVip->wait)//需要插队的为普通客户
{
cout << "Time " << time << ": customer " << aAlarm.needInsertNormal->num << " wait " << maxWaitNormal << " ! INSERT!" << endl;
customer* tmp = normalQueue.nextNormal(aAlarm.needInsertNormal);//插队的下一个客户即为需要关注的插队对象
normalQueue.insert(aAlarm.needInsertNormal);//插队
aAlarm.needInsertNormal = tmp;
}
else if (aAlarm.needInsertNormal->wait >= aAlarm.needInsertVip->wait)
{
cout << "Time " << time << ": customer " << aAlarm.needInsertVip->num << "(VIP) wait " << maxWaitVip << " ! INSERT!" << endl;
customer* tmp = normalQueue.nextVIP(aAlarm.needInsertVip);//插队的下一个客户即为需要关注的插队对象
normalQueue.insert(aAlarm.needInsertVip);//插队
aAlarm.needInsertVip = tmp;
}
}
}
if (aAlarm.needInsertNormal == NULL && aAlarm.needInsertVip == NULL)
aAlarm.nextInsertTime = aAlarm.nextArriveTime;
else if (aAlarm.needInsertNormal == NULL)
aAlarm.nextInsertTime = aAlarm.needInsertVip->wait;
else if (aAlarm.needInsertVip == NULL)
aAlarm.nextInsertTime = aAlarm.needInsertNormal->wait;
else if ( aAlarm.needInsertNormal->wait < aAlarm.needInsertVip->wait)
aAlarm.nextInsertTime = aAlarm.needInsertNormal->wait;
else if (aAlarm.needInsertNormal->wait >= aAlarm.needInsertVip->wait)
aAlarm.nextInsertTime = aAlarm.needInsertVip->wait;
aAlarm.setnext();
time = aAlarm.nextResponce;
}
aAlarm.nextArriveTime = MAX_TIME;
while (time < MAX_TIME)//处理剩余客户
{
if (aAlarm.nextType == 1) //一个客户离开
{
if (tellers[aAlarm.nextTeller].servenow != NULL)//柜台不为空
tellers[aAlarm.nextTeller].free(time);
if (!normalQueue.isempty()) {
customer* cus = normalQueue.leave(); // 从普通队列中取出顾客
if (cus == aAlarm.needInsertVip)
aAlarm.needInsertVip = normalQueue.nextVIP(cus);
if (cus == aAlarm.needInsertNormal)
aAlarm.needInsertNormal = normalQueue.nextNormal(cus);
tellers[aAlarm.nextTeller].servenow = cus;
tellers[aAlarm.nextTeller].arriveacustomer(time);
}
else//队列为空
{
tellers[aAlarm.nextTeller].flashleavetime(MAX_TIME);
}
//设置下一个响应时间和柜台
aAlarm.nextTeller = tellermonitor.checktime();
aAlarm.nextLeaveTime = tellers[aAlarm.nextTeller].leavetime();
}
}
附录(源码等)
sim1.cpp 和 que.h 为第一问代码
sim2.cpp,sim3.cpp,sim4.cpp 分别为第二三四问代码。
que.h:
#pragma once
#include <iostream>
#include <stdlib.h>
using namespace std;
struct customer
{
int num;//
int Type;//是否为vip
int arrivetime;//到达时间
int startserve;//开始服务的时间
int leavetime;//离开时
customer* next;//指向下一个的指针
};//顾客结构体
class queue
{
private:
customer* start;//队首
customer* end;//队尾
int count;//队列长度(?)
public:
queue(void);
void add(customer* newcust);//用户入队
customer* leave();//队首离队
int isempty();
};
queue::queue()
{
count = 0;
start = end = NULL;
}
void queue::add(customer* newcust)
{
if (start == NULL)
{
start = end = newcust;
}
else
{
end->next = newcust;
end = newcust;
}
end->next = NULL;
count++;
}
customer* queue::leave()
{
customer* tmp = start;
start = start->next;
count--;
return tmp;
}
int queue::isempty()
{
return int(count == 0);
}
sim1.cpp:
#include <iostream>
using namespace std;
#include "random.h"
#include "que.h"
#define MAX_TIME 1000000
class teller//单个柜台
{
private:
int number;
int isEmpty;//0空闲,1有人
//int time;//服务停止时间时间
int serviceHigh;
int serviceLow;
RandomNumber rnd;
public:
int time;//服务停止时间时间
customer* servenow;//正在服务的顾客的对象
teller();
int type;// 0-普通 1-vip
void init(int num, int servHigh, int servLow, int atype, RandomNumber ran);//初始化柜台号和服务最长最短时间
int empty();//查询柜台是否为空
void arriveacustomer(int arrtime);//有客户到达设置离开时间
void free(int time);//客户离开释放柜台
int leavetime();//查询空闲的时间
void flashleavetime(int nexttime);//在无客户时刷新下一个服务时间。
};
teller::teller()
{
time = 0;
isEmpty = 0;
type = -1;
serviceLow = -1;
serviceHigh = -1;
servenow = NULL;
number = -1;
}
void teller::init(int num, int servHigh, int servLow, int atype, RandomNumber ran)
{
rnd = ran;
number = num;
serviceHigh = servHigh;
serviceLow = servLow;
type = atype;
}
int teller::empty()
{
return isEmpty;
}
void teller::arriveacustomer(int arrtime)
{
isEmpty = 1;
time = arrtime + rnd.Random(serviceHigh - serviceLow + 1) + serviceLow;
if (type == 0)
cout << "Time " << arrtime << ": customer " << servenow->num << " arrive teller " << number << endl;
else
cout << "Time " << arrtime << ": customer " << servenow->num << "(VIP) arrive VIP teller " << number << endl;
}
void teller::free(int time)
{
if (type == 1)
cout << "Time " << time << ": VIP teller " << number << " serve over," << " customer " << servenow->num << " leave" << endl;
else
cout << "Time " << time << ": teller " << number << " serve over," << " customer " << servenow->num << " leave" << endl;
time = 0;
isEmpty = 0;
servenow->leavetime = 0;
customer* tmp = servenow;
servenow = NULL;
//delete tmp;
}
int teller::leavetime()
{
return time;
}
void teller::flashleavetime(int nexttime)
{
time = nexttime;
}
class monitor//仅用于管理柜台(?)
{
private:
teller* Tellers;
int numTeller;
public:
monitor(teller* tellers, int num)
{
Tellers = tellers;
numTeller = num;
}
int checktime();//检查下一个可服务时间
};
int monitor::checktime()
{
int lesstime = Tellers[0].leavetime();
int j = 0;
for (int i = 1; i < numTeller; i++)
{
if (Tellers[i].leavetime() < lesstime)
{
lesstime = Tellers[i].leavetime();
j = i;
}
}
return j;//返回柜台号,在柜台处查询信息
}
class alarm//设置时间
{
public:
int nextTeller;
int nextArriveTime;
int nextLeaveTime;
int nextResponce;//下一个待处理的时间
int nextType;// -1 无, 0 顾客到达 ,1 顾客离开
alarm(void);
void setnext();//刷新
};
alarm::alarm(void)
{
nextArriveTime = nextLeaveTime = 0;
nextResponce = -1;
nextType = -1;
nextTeller = 0;
}
void alarm::setnext()
{
if (nextArriveTime > nextLeaveTime)
{
nextResponce = nextLeaveTime;
nextType = 1;
}
else
{
nextResponce = nextArriveTime;
nextType = 0;
}
}
void initCustomer(customer* a, int time, int customNum, RandomNumber rnd)//初始化一个顾客,生成id和类型,保存传入的时间以便后续计算总等待时间。
{
a->arrivetime = time;
a->leavetime = MAX_TIME;
a->next = NULL;
a->num = customNum;
a->startserve = MAX_TIME;
a->Type = a->num%2;
if (a->Type == 0)
cout << "Time " << time << ": customer " << customNum << " arrive." << endl;
else
cout << "Time " << time << ": custome " << customNum << " (VIP) arrive." << endl;
}
int rndNext(RandomNumber rnd, int arrLow, int arrHigh, int time)//生成下一个出现客户的时间
{
return rnd.Random(arrHigh - arrLow) + arrLow + time;
}
int main()
{
int simulationLength;
int numTellers;
int numVipTellers;
int arrivalLow, arrivalHigh;
int serviceLow, serviceHigh;
queue normalQueue;
queue vipQueue;
RandomNumber rnd;
alarm aAlarm;
cout << "Enter the simulation time in minutes: ";
cin >> simulationLength;
cout << "Enter the number of normal tellers: ";
cin >> numTellers;
cout << "Enter the number of vip tellers: ";
cin >> numVipTellers;
cout << "Enter the range of arrival times in minutes: ";
cin >> arrivalLow >> arrivalHigh;
cout << "Enter the range of service times in minutes: ";
cin >> serviceLow >> serviceHigh;
customer* first = new customer();
initCustomer(first, 0, 1, rnd);//设置第一个顾客并插入对应队列
if (first->Type == 0)
{
normalQueue.add(first);
aAlarm.nextTeller = 1;
}
else
{
vipQueue.add(first);
aAlarm.nextTeller = 0;
}
teller* tellers = new teller[numTellers+ numVipTellers];
for (int i = 0; i < (numTellers + numVipTellers); i++)
{
tellers[i].init(i, serviceHigh, serviceLow, int(i < numVipTellers), rnd);
}
int customercount = 2;
int time = 0;
monitor tellermonitor(tellers, (numTellers + numVipTellers));
aAlarm.nextArriveTime = rndNext(rnd, arrivalLow, arrivalHigh, time);
if (first->Type == 0)
{
normalQueue.leave();
}
else
{
vipQueue.leave();
}
tellers[aAlarm.nextTeller].servenow = first;
tellers[aAlarm.nextTeller].arriveacustomer(time);
aAlarm.nextTeller = tellermonitor.checktime();
aAlarm.nextLeaveTime = tellers[aAlarm.nextTeller].leavetime();
aAlarm.setnext();
time = aAlarm.nextResponce;
while (time <= simulationLength )
{
//for (int i = 0; i < (numTellers + numVipTellers); i++)
//{
// cout <<"Teller:" << i << "\t" << tellers[i].time << endl;
//}
//cout << time << "\t" << aAlarm.nextArriveTime << "\t" << aAlarm.nextLeaveTime << "\t" << aAlarm.nextResponce << "\t" << aAlarm.nextType << endl;
if (aAlarm.nextType == 0)//到达一个客户
{
customer* newCustomer = new customer;
initCustomer(newCustomer, time, customercount, rnd);
if (newCustomer->Type == 0)
normalQueue.add(newCustomer);
else
vipQueue.add(newCustomer);
customercount += 1;
aAlarm.nextArriveTime = rndNext(rnd, arrivalLow, arrivalHigh, time);
//cout << time << "\t" << aAlarm.nextArriveTime << "\t" << aAlarm.nextLeaveTime << "\t" << aAlarm.nextResponce << "\t" << aAlarm.nextType << endl;
}
else if (aAlarm.nextType == 1) //一个客户离开
{
if (tellers[aAlarm.nextTeller].servenow != NULL)//柜台不为空
tellers[aAlarm.nextTeller].free(time);
if (tellers[aAlarm.nextTeller].type == 1)//检查柜台类型,从对应的队列出列一人至窗口
{
if (!vipQueue.isempty()) {
customer* cus = vipQueue.leave(); // 从VIP队列中取出顾客
tellers[aAlarm.nextTeller].servenow = cus;
tellers[aAlarm.nextTeller].arriveacustomer(time);
}
else//队列为空
tellers[aAlarm.nextTeller].flashleavetime(aAlarm.nextArriveTime);
}
else
{
if (!normalQueue.isempty()) {
customer* cus = normalQueue.leave(); // 从普通队列中取出顾客
tellers[aAlarm.nextTeller].servenow = cus;
tellers[aAlarm.nextTeller].arriveacustomer(time);
}
else//队列为空
{
tellers[aAlarm.nextTeller].flashleavetime(aAlarm.nextArriveTime);
}
}
//设置下一个响应时间和柜台
aAlarm.nextTeller = tellermonitor.checktime();
aAlarm.nextLeaveTime = tellers[aAlarm.nextTeller].leavetime();
}
aAlarm.setnext();
time = aAlarm.nextResponce;
}
while (time<MAX_TIME)//处理剩余客户
{
if (tellers[aAlarm.nextTeller].servenow != NULL)//柜台不为空
tellers[aAlarm.nextTeller].free(time);
if (tellers[aAlarm.nextTeller].type == 1)//检查柜台类型,从对应的队列出列一人至窗口
{
if (!vipQueue.isempty()) {
customer* cus = vipQueue.leave(); // 从VIP队列中取出顾客
tellers[aAlarm.nextTeller].servenow = cus;
tellers[aAlarm.nextTeller].arriveacustomer(time);
}
else//队列为空
tellers[aAlarm.nextTeller].flashleavetime(MAX_TIME);//队列已服务完则将时间置为最大
}
else
{
if (!normalQueue.isempty()) {
customer* cus = normalQueue.leave(); // 从普通队列中取出顾客
tellers[aAlarm.nextTeller].servenow = cus;
tellers[aAlarm.nextTeller].arriveacustomer(time);
}
else//队列为空
tellers[aAlarm.nextTeller].flashleavetime(MAX_TIME);
}
//设置下一个响应时间和柜台
aAlarm.nextTeller = tellermonitor.checktime();
aAlarm.nextLeaveTime = tellers[aAlarm.nextTeller].leavetime();
time = aAlarm.nextLeaveTime;
}
delete[]tellers;
return 0;
}
sim2.cpp:
#pragma once
#include <iostream>
#include <stdlib.h>
#include "random.h"
#define MAX_TIME 1000000
using namespace std;
struct customer
{
int num;//
int Type;//是否为vip
int arrivetime;//到达时间
int startserve;//开始服务的时间
int leavetime;//离开时
int insert;//是否插队过
customer* next;//指向下一个的指针
};//顾客结构体
class queue
{
private:
customer* start;//队首
customer* end;//队尾
int count;//队列长度(?)
public:
queue(void);
void insert(customer* newcust);
void add(customer* newcust);//用户入队
customer* leave();//队首离队
int isempty();
void print();
};
queue::queue()
{
count = 0;
start = end = NULL;
}
void queue::print()
{
customer* tmp =start;
while(tmp!= NULL)
{
cout<<tmp->num<<"->";
tmp = tmp->next;
}
cout<<endl;
}
void queue::add(customer* newcust)
{
if (start == NULL)
{
start = end = newcust;
}
else
{
end->next = newcust;
end = newcust;
}
end->next = NULL;
count++;
}
customer* queue::leave()
{
customer* tmp = start;
start = start->next;
count--;
return tmp;
}
int queue::isempty()
{
return int(count == 0);
};
void queue::insert(customer* newcust)//实现插队
{
cout<<"customer "<<newcust->num<<"(VIP) insert."<<endl<<"Befor insert:";
print();
newcust->insert = 1;
customer* tmp = start;
if (start == NULL)//队列为空直接加入队列
add(newcust);
else
{
if (tmp->insert == 0)
{
newcust->next = tmp;
start = newcust;
}
else
{
while (tmp->next)
{
if (tmp->next->insert == 0)
break;
tmp = tmp->next;
}
newcust->next = tmp->next;
tmp->next = newcust;
}
}
cout<<"After insert:";
print();
}
class teller//单个柜台
{
private:
int number;
int isEmpty;//0空闲,1有人
//int time;//服务停止时间时间
int serviceHigh;
int serviceLow;
RandomNumber rnd;
public:
int time;//服务停止时间时间
//正在服务的顾客的对象
customer* servenow;
teller();
void init(int num, int servHigh, int servLow, RandomNumber ran);//初始化柜台号和服务最长最短时间
int empty();//查询柜台是否为空
void arriveacustomer(int arrtime);//有客户到达设置离开时间
void free(int time);//客户离开释放柜台
int leavetime();//查询空闲的时间
void flashleavetime(int nexttime);//在无客户时刷新下一个服务时间。
};
teller::teller()
{
time = 0;
isEmpty = 0;
serviceLow = -1;
serviceHigh = -1;
servenow = NULL;
number = -1;
}
void teller::init(int num, int servHigh, int servLow, RandomNumber ran)
{
rnd = ran;
number = num;
serviceHigh = servHigh;
}
int teller::empty()
{
return isEmpty;
}
void teller::arriveacustomer(int arrtime)
{
isEmpty = 1;
time = arrtime + rnd.Random(serviceHigh - serviceLow + 1) + serviceLow;
if (servenow->Type == 0)
cout << "Time " << arrtime << ": customer " << servenow->num << " arrive teller " << number <<" . serve over time : "<<time<< endl;
else
cout << "Time " << arrtime << ": customer " << servenow->num << "(VIP) arrive teller " << number <<" . serve over time : "<<time<< endl;
}
void teller::free(int time)
{
if (servenow->Type == 1)
cout << "Time " << time << ": teller " << number << " serve over," << " customer " << servenow->num << "(VIP) leave" << endl;
else
cout << "Time " << time << ": teller " << number << " serve over," << " customer " << servenow->num << " leave" << endl;
time = 0;
isEmpty = 0;
servenow->leavetime = 0;
customer* tmp = servenow;
servenow = NULL;
//delete tmp;
}
int teller::leavetime()
{
return time;
}
void teller::flashleavetime(int nexttime)
{
time = nexttime;
}
class monitor//仅用于管理柜台(?)
{
private:
teller* Tellers;
int numTeller;
public:
monitor(teller* tellers, int num)
{
Tellers = tellers;
numTeller = num;
}
int checktime();//检查下一个可服务时间
};
int monitor::checktime()
{
int lesstime = Tellers[0].leavetime();
int j = 0;
for (int i = 1; i < numTeller; i++)
{
if (Tellers[i].leavetime() < lesstime)
{
lesstime = Tellers[i].leavetime();
j = i;
}
}
return j;//返回柜台号,在柜台处查询信息
}
class alarm//设置时间//可考虑修改为结构体
{
public:
int nextTeller;
int nextArriveTime;
int nextLeaveTime;
int nextResponce;//下一个待处理的时间
int nextType;// -1 无, 0 顾客到达 ,1 顾客离开
alarm(void);
void setnext();//刷新
};
alarm::alarm(void)
{
nextArriveTime = nextLeaveTime = 0;
nextResponce = -1;
nextType = -1;
nextTeller = 0;
}
void alarm::setnext()
{
if (nextArriveTime > nextLeaveTime)
{
nextResponce = nextLeaveTime;
nextType = 1;
}
else
{
nextResponce = nextArriveTime;
nextType = 0;
}
}
void initCustomer(customer* a, int time, int customNum, RandomNumber rnd)//初始化一个顾客,生成id和类型,保存传入的时间以便后续计算总等待时间。
{
a->arrivetime = time;
a->leavetime = MAX_TIME;
a->next = NULL;
a->num = customNum;
a->startserve = MAX_TIME;
a->Type = a->num%2;
a->insert = 0;
if (a->Type == 0)
cout << "Time " << time << ": customer " << customNum << " arrive." << endl;
else
cout << "Time " << time << ": custome " << customNum << " (VIP) arrive." << endl;
}
int rndNext(RandomNumber rnd, int arrLow, int arrHigh, int time)//生成下一个出现客户的时间
{
return rnd.Random(arrHigh - arrLow) + arrLow + time;
}
int main()
{
int simulationLength;
int numTellers;
int arrivalLow, arrivalHigh;
int serviceLow, serviceHigh;
queue normalQueue;
RandomNumber rnd;
alarm aAlarm;
cout << "Enter the simulation time in minutes: ";
cin >> simulationLength;
cout << "Enter the number of normal tellers: ";
cin >> numTellers;
cout << "Enter the range of arrival times in minutes: ";
cin >> arrivalLow >> arrivalHigh;
cout << "Enter the range of service times in minutes: ";
cin >> serviceLow >> serviceHigh;
customer* first = new customer();
initCustomer(first, 0, 1, rnd);//设置第一个顾客并插入对应队列
normalQueue.add(first);
teller* tellers = new teller[numTellers];
for (int i = 0; i < (numTellers); i++)
{
tellers[i].init(i, serviceHigh, serviceLow, rnd);
}
int customercount = 2;
int time = 0;
monitor tellermonitor(tellers, numTellers);
aAlarm.nextArriveTime = rndNext(rnd, arrivalLow, arrivalHigh, time);
normalQueue.leave();
tellers[aAlarm.nextTeller].servenow = first;
tellers[aAlarm.nextTeller].arriveacustomer(time);
aAlarm.nextTeller = tellermonitor.checktime();
aAlarm.nextLeaveTime = tellers[aAlarm.nextTeller].leavetime();
aAlarm.setnext();
//cout << tellermonitor.checktime() << endl;
time = aAlarm.nextResponce;
while (time <= simulationLength)
{
if (aAlarm.nextType == 0)//到达一个客户
{
customer* newCustomer = new customer;
initCustomer(newCustomer, time, customercount, rnd);
if (newCustomer->Type == 0)
normalQueue.add(newCustomer);
else
normalQueue.insert(newCustomer);
customercount += 1;
aAlarm.nextArriveTime = rndNext(rnd, arrivalLow, arrivalHigh, time);
//cout << time << "\t" << aAlarm.nextArriveTime << "\t" << aAlarm.nextLeaveTime << "\t" << aAlarm.nextResponce << "\t" << aAlarm.nextType << endl;
}
else if (aAlarm.nextType == 1) //一个客户离开
{
if (tellers[aAlarm.nextTeller].servenow != NULL)//柜台不为空
tellers[aAlarm.nextTeller].free(time);
if (!normalQueue.isempty()) {
customer* cus = normalQueue.leave(); // 从普通队列中取出顾客
tellers[aAlarm.nextTeller].servenow = cus;
tellers[aAlarm.nextTeller].arriveacustomer(time);
}
else//队列为空
{
tellers[aAlarm.nextTeller].flashleavetime(aAlarm.nextArriveTime);
}
//设置下一个响应时间和柜台
aAlarm.nextTeller = tellermonitor.checktime();
aAlarm.nextLeaveTime = tellers[aAlarm.nextTeller].leavetime();
}
aAlarm.setnext();
time = aAlarm.nextResponce;
}
while (time < MAX_TIME)//处理剩余客户
{
if (tellers[aAlarm.nextTeller].servenow != NULL)//柜台不为空
tellers[aAlarm.nextTeller].free(time);
if (!normalQueue.isempty()) {
customer* cus = normalQueue.leave(); // 从普通队列中取出顾客
tellers[aAlarm.nextTeller].servenow = cus;
tellers[aAlarm.nextTeller].arriveacustomer(time);
}
else//队列为空
{
tellers[aAlarm.nextTeller].flashleavetime(MAX_TIME);
}
//设置下一个响应时间和柜台
aAlarm.nextTeller = tellermonitor.checktime();
aAlarm.nextLeaveTime = tellers[aAlarm.nextTeller].leavetime();
time = aAlarm.nextLeaveTime;
}
delete[]tellers;
return 0;
}
sim3.cpp:
#pragma once
#include <iostream>
#include <stdlib.h>
#include "random.h"
#define MAX_TIME 1000000
using namespace std;
struct customer
{
int num;//顾客号
int Type;//是否为vip
int arrivetime;//到达时间
int startserve;//开始服务的时间
int leavetime;//离开时
int insert;//是否插队过
int wait;//等待时限
customer* next;//指向下一个的指针
};//顾客结构体
class queue
{
private:
customer* start;//队首
customer* end;//队尾
int count;//队列长度(?)
public:
queue(void);
void insert(customer* newcust);
void add(customer* newcust);//用户入队
customer* leave();//队首离队
customer* del(customer* newcust);//从后面的队列中删去
customer* nextVIP(customer* vip);
void print();
int isempty();
};
queue::queue()
{
count = 0;
start = end = NULL;
}
void queue::add(customer* newcust)
{
if (start == NULL)
{
start = end = newcust;
}
else
{
end->next = newcust;
end = newcust;
}
end->next = NULL;
count++;
}
void queue::print()
{
customer* tmp = start;
while (tmp != NULL)
{
cout << tmp->num << "->";
tmp = tmp->next;
}
cout << endl;
}
customer* queue::leave()
{
customer* tmp = start;
start = start->next;
count--;
return tmp;
}
int queue::isempty()
{
return int(count == 0);
};
void queue::insert(customer* newcust)//实现插队
{
cout << "customer " << newcust->num << "(VIP) insert." << endl << "Befor insert:";
print();
newcust->insert = 1;
customer* tmp = start;
if (start != NULL)
{
if (newcust != start)
{
del(newcust);
if (tmp->insert == 0)
{
newcust->next = tmp;
start = newcust;
}
else
{
while (tmp->next)
{
if (tmp->next->insert == 0)
break;
tmp = tmp->next;
}
newcust->next = tmp->next;
tmp->next = newcust;
}
}
}
cout << "After insert:";
print();
}
customer* queue::del(customer* newcust)
{
customer* tmp = start;
while (tmp!=NULL && tmp->next != newcust)
tmp = tmp->next;
tmp->next = newcust->next;
return newcust;
}
customer* queue::nextVIP(customer* vip)
{
customer* tmp = vip->next;
while (tmp)
{
if (tmp->Type == 1)
return tmp;
tmp = tmp->next;
}
return NULL;
}
class teller//单个柜台
{
private:
int number;
int isEmpty;//0空闲,1有人
//int time;//服务停止时间时间
int serviceHigh;
int serviceLow;
RandomNumber rnd;
public:
int time;//服务停止时间时间
//正在服务的顾客的对象
customer* servenow;
teller();
void init(int num, int servHigh, int servLow, RandomNumber ran);//初始化柜台号和服务最长最短时间
int empty();//查询柜台是否为空
void arriveacustomer(int arrtime);//有客户到达设置离开时间
void free(int time);//客户离开释放柜台
int leavetime();//查询空闲的时间
void flashleavetime(int nexttime);//在无客户时刷新下一个服务时间。
};
teller::teller()
{
time = 0;
isEmpty = 0;
serviceLow = -1;
serviceHigh = -1;
servenow = NULL;
number = -1;
}
void teller::init(int num, int servHigh, int servLow, RandomNumber ran)
{
rnd = ran;
number = num;
serviceHigh = servHigh;
}
int teller::empty()
{
return isEmpty;
}
void teller::arriveacustomer(int arrtime)
{
isEmpty = 1;
time = arrtime + rnd.Random(serviceHigh - serviceLow + 1) + serviceLow;
if (servenow->Type == 0)
cout << "Time " << arrtime << ": customer " << servenow->num << " arrive teller " << number <<" . serve over time : "<<time<< endl;
else
cout << "Time " << arrtime << ": customer " << servenow->num << "(VIP) arrive teller " << number <<" . serve over time : "<<time<< endl;
}
void teller::free(int time)
{
if (servenow->Type == 1)
cout << "Time " << time << ": teller " << number << " serve over," << " customer " << servenow->num << "(VIP) leave" << endl;
else
cout << "Time " << time << ": teller " << number << " serve over," << " customer " << servenow->num << " leave" << endl;
time = 0;
isEmpty = 0;
servenow->leavetime = 0;
customer* tmp = servenow;
servenow = NULL;
//delete tmp;
}
int teller::leavetime()
{
return time;
}
void teller::flashleavetime(int nexttime)//队列为空时刷新柜台时间
{
time = nexttime;
}
class monitor//仅用于管理柜台
{
private:
teller* Tellers;
int numTeller;
public:
monitor(teller* tellers, int num)
{
Tellers = tellers;
numTeller = num;
}
int checktime();//检查下一个可服务时间
void print()
{
for(int i =0;i<numTeller;i++)
{
cout<<i<<":"<<Tellers[i].leavetime()<<"\t";
}
cout<<endl;
}
};
int monitor::checktime()
{
int lesstime = Tellers[0].leavetime();
int j = 0;
for (int i = 1; i < numTeller; i++)
{
if (Tellers[i].leavetime() < lesstime)
{
lesstime = Tellers[i].leavetime();
j = i;
}
}
return j;//返回柜台号,在柜台处查询信息
}
class alarm//设置时间//可考虑修改为结构体
{
public:
int nextTeller;
int nextArriveTime;
int nextLeaveTime;
int nextInsertTIme;//需要插队的时间
customer* needInsert;//可能需要插队的顾客
int nextResponce;//下一个待处理的时间
int nextType;// -1 无, 0 顾客到达 ,1 顾客离开 ,2 需要插队
alarm(void);
void setnext();//刷新
};
alarm::alarm(void)
{
nextArriveTime = nextLeaveTime = 0;
nextResponce = -1;
nextType = -1;
nextTeller = 0;
needInsert = NULL;
nextInsertTIme = MAX_TIME;
}
void alarm::setnext()//同一时间处理优先级为:顾客到达->顾客插队->顾客离开柜台。
{
if (nextArriveTime > nextLeaveTime)
{
if (nextInsertTIme > nextLeaveTime)
{
nextResponce = nextLeaveTime;
nextType = 1;
}
else
{
nextResponce = nextInsertTIme;
nextType = 2;
}
}
else
{
if (nextInsertTIme >= nextArriveTime)
{
nextResponce = nextArriveTime;
nextType = 0;
}
else
{
nextResponce = nextInsertTIme;
nextType = 2;
}
}
}
void initCustomer(customer* a, int time, int customNum, int maxWait, RandomNumber rnd)//初始化一个顾客,生成id和类型,保存传入的时间以便后续计算总等待时间。
{
a->arrivetime = time;
a->insert = 0;
a->leavetime = MAX_TIME;
a->next = NULL;
a->num = customNum;
a->startserve = MAX_TIME;
a->Type = a->num % 2;
if (a->Type == 0)
{
a->wait = MAX_TIME;
cout << "Time " << time << ": customer " << customNum << " arrive." << endl;
}
else
{
a->wait = time + maxWait;
cout << "Time " << time << ": custome " << customNum << " (VIP) arrive." << endl;
}
}
int rndNext(RandomNumber rnd, int arrLow, int arrHigh, int time)//生成下一个出现客户的时间
{
return rnd.Random(arrHigh - arrLow + 1) + arrLow + time;
}
int main()
{
int simulationLength;
int numTellers;
int maxWait;
int arrivalLow, arrivalHigh;
int serviceLow, serviceHigh;
queue normalQueue;
RandomNumber rnd;
alarm aAlarm;
cout << "Enter the simulation time in minutes: ";
cin >> simulationLength;
cout << "Enter the number of normal tellers: ";
cin >> numTellers;
cout << "Enter the maximum waiting time: ";
cin >> maxWait;
cout << "Enter the range of arrival times in minutes: ";
cin >> arrivalLow >> arrivalHigh;
cout << "Enter the range of service times in minutes: ";
cin >> serviceLow >> serviceHigh;
customer* first = new customer();
initCustomer(first, 0, 1, maxWait, rnd);//设置第一个顾客并插入对应队列
normalQueue.add(first);
teller* tellers = new teller[numTellers];
for (int i = 0; i < (numTellers); i++)
{
tellers[i].init(i, serviceHigh, serviceLow, rnd);
}
int customercount = 2;
int time = 0;
monitor tellermonitor(tellers, numTellers);
aAlarm.nextArriveTime = rndNext(rnd, arrivalLow, arrivalHigh, time);
normalQueue.leave();
tellers[aAlarm.nextTeller].servenow = first;
tellers[aAlarm.nextTeller].arriveacustomer(time);
aAlarm.nextTeller = tellermonitor.checktime();
aAlarm.nextLeaveTime = tellers[aAlarm.nextTeller].leavetime();
aAlarm.setnext();
time = aAlarm.nextResponce;
while (time <= simulationLength)
{
//normalQueue.print();
// tellermonitor.print();
// cout<<aAlarm.nextTeller<<endl;
//cout << time << "\t" << aAlarm.nextArriveTime << "\t" << aAlarm.nextLeaveTime << "\t" << aAlarm.nextResponce << "\t" <<aAlarm.nextInsertTIme<<"\t"<< aAlarm.nextType << endl;
if (aAlarm.nextType == 0)//到达一个客户
{
customer* newCustomer = new customer;
initCustomer(newCustomer, time, customercount, maxWait, rnd);
normalQueue.add(newCustomer);
if (aAlarm.needInsert == NULL && newCustomer->Type == 1)//目前未有闹钟客户
{
aAlarm.needInsert = newCustomer;
aAlarm.nextInsertTIme = time + maxWait;
}
customercount += 1;
aAlarm.nextArriveTime = rndNext(rnd, arrivalLow, arrivalHigh, time);
}
else if (aAlarm.nextType == 1) //一个客户离开
{
if (tellers[aAlarm.nextTeller].servenow != NULL)//柜台不为空
tellers[aAlarm.nextTeller].free(time);
if (!normalQueue.isempty()) {
customer* cus = normalQueue.leave(); // 从普通队列中取出顾客
if (cus == aAlarm.needInsert )//设着闹钟的顾客出列了
{
aAlarm.needInsert = normalQueue.nextVIP(cus);
if(aAlarm.needInsert != NULL)
aAlarm.nextInsertTIme = aAlarm.needInsert->wait;
}
tellers[aAlarm.nextTeller].servenow = cus;
tellers[aAlarm.nextTeller].arriveacustomer(time);
}
else//队列为空
{
tellers[aAlarm.nextTeller].flashleavetime(aAlarm.nextArriveTime);
}
//设置下一个响应时间和柜台
aAlarm.nextTeller = tellermonitor.checktime();
aAlarm.nextLeaveTime = tellers[aAlarm.nextTeller].leavetime();
}
else if (aAlarm.nextType == 2)//有一个顾客要插队。
{
if (aAlarm.needInsert != NULL)
{
cout << "Time " << time << ": customer " << aAlarm.needInsert->num << " wait " << maxWait << " ! INSERT!" << endl;
customer* tmp = normalQueue.nextVIP(aAlarm.needInsert);//插队的VIP的下一个VIP即为需要关注的插队对象
normalQueue.insert(aAlarm.needInsert);//VIP插队
if (tmp != NULL)
aAlarm.nextInsertTIme = tmp->wait;
else
aAlarm.nextInsertTIme = aAlarm.nextArriveTime;
aAlarm.needInsert = tmp;
}
else
aAlarm.nextInsertTIme = aAlarm.nextArriveTime;
}
aAlarm.setnext();
time = aAlarm.nextResponce;
}
aAlarm.nextArriveTime = MAX_TIME;
while (time < MAX_TIME)//处理剩余客户
{
if (aAlarm.nextType == 1) //一个客户离开
{
if (tellers[aAlarm.nextTeller].servenow != NULL)//柜台不为空
tellers[aAlarm.nextTeller].free(time);
if (!normalQueue.isempty()) {
customer* cus = normalQueue.leave(); // 从普通队列中取出顾客
if (cus == aAlarm.needInsert)//设着闹钟的顾客出列了
{
aAlarm.needInsert = normalQueue.nextVIP(cus);
if (aAlarm.needInsert != NULL)
aAlarm.nextInsertTIme = aAlarm.needInsert->wait;
}
tellers[aAlarm.nextTeller].servenow = cus;
tellers[aAlarm.nextTeller].arriveacustomer(time);
}
else//队列为空
{
tellers[aAlarm.nextTeller].flashleavetime(aAlarm.nextArriveTime);
}
//设置下一个响应时间和柜台
aAlarm.nextTeller = tellermonitor.checktime();
aAlarm.nextLeaveTime = tellers[aAlarm.nextTeller].leavetime();
}
else if (aAlarm.nextType == 2)//有一个顾客要插队。
{
if (aAlarm.needInsert != NULL)
{
cout << "Time " << time << ": customer " << aAlarm.needInsert->num << " wait " << maxWait << " ! INSERT!" << endl;
customer* tmp = normalQueue.nextVIP(aAlarm.needInsert);//插队的VIP的下一个VIP即为需要关注的插队对象
normalQueue.insert(aAlarm.needInsert);//VIP插队
if (tmp != NULL)
aAlarm.nextInsertTIme = tmp->wait;
else
aAlarm.nextInsertTIme = aAlarm.nextArriveTime;
aAlarm.needInsert = tmp;
}
else
aAlarm.nextInsertTIme = aAlarm.nextArriveTime;
}
aAlarm.setnext();
time = aAlarm.nextResponce;
}
delete[]tellers;
return 0;
}
sim4.cpp:
#pragma once
#include <iostream>
#include <stdlib.h>
#include "random.h"
#define MAX_TIME 1000000
using namespace std;
struct customer
{
int num;//顾客号
int Type;//是否为vip
int arrivetime;//到达时间
int startserve;//开始服务的时间
int leavetime;//离开时
int insert;//是否插队过
int wait;//等待时限
customer* next;//指向下一个的指针
};//顾客结构体
class queue
{
private:
customer* start;//队首
customer* end;//队尾
int count;//队列长度(?)
public:
queue(void);
void insert(customer* newcust);
void add(customer* newcust);//用户入队
void print();
customer* leave();//队首离队
customer* del(customer* newcust);
customer* nextVIP(customer* vip);
customer* nextNormal(customer* normal);
int isempty();
};
queue::queue()
{
count = 0;
start = end = NULL;
}
void queue::add(customer* newcust)
{
if (start == NULL)
{
start = end = newcust;
}
else
{
end->next = newcust;
end = newcust;
}
end->next = NULL;
count++;
}
customer* queue::leave()
{
customer* tmp = start;
start = start->next;
count--;
return tmp;
}
int queue::isempty()
{
return int(count == 0);
};
void queue::insert(customer* newcust)//实现插队
{
if (newcust->Type ==1)
cout << "customer " << newcust->num << "(VIP) insert." << endl << "Befor insert:";
else
cout << "customer " << newcust->num << " insert." << endl << "Befor insert:";
print();
newcust->insert = 1;
customer* tmp = start;
if (start != NULL)
{
if (newcust != start)
{
del(newcust);
if (tmp->insert == 0)
{
newcust->next = tmp;
start = newcust;
}
else
{
while (tmp->next)
{
if (tmp->next->insert == 0)
break;
tmp = tmp->next;
}
newcust->next = tmp->next;
tmp->next = newcust;
}
}
}
cout << "After insert:";
print();
}
void queue::print()
{
customer* tmp =start;
while(tmp!= NULL)
{
cout<<tmp->num<<"->";
tmp = tmp->next;
}
cout<<endl;
}
customer* queue::del(customer* newcust)
{
customer* tmp = start;
while (tmp->next != newcust)
tmp = tmp->next;
tmp->next = newcust->next;
return newcust;
}
customer* queue::nextVIP(customer* vip)
{
customer* tmp = vip->next;
while (tmp)
{
if (tmp->Type == 1)
return tmp;
tmp = tmp->next;
}
return NULL;
}
customer* queue::nextNormal (customer* normal)
{
customer* tmp = normal->next;
while (tmp)
{
if (tmp->Type == 0)
return tmp;
tmp = tmp->next;
}
return NULL;
}
class teller//单个柜台
{
private:
int number;
int isEmpty;//0空闲,1有人
//int time;//服务停止时间时间
int serviceHigh;
int serviceLow;
RandomNumber rnd;
public:
int time;//服务停止时间时间
//正在服务的顾客的对象
customer* servenow;
teller();
void init(int num, int servHigh, int servLow, RandomNumber ran);//初始化柜台号和服务最长最短时间
int empty();//查询柜台是否为空
void arriveacustomer(int arrtime);//有客户到达设置离开时间
void free(int time);//客户离开释放柜台
int leavetime();//查询空闲的时间
void flashleavetime(int nexttime);//在无客户时刷新下一个服务时间。
};
teller::teller()
{
time = 0;
isEmpty = 0;
serviceLow = -1;
serviceHigh = -1;
servenow = NULL;
number = -1;
}
void teller::init(int num, int servHigh, int servLow, RandomNumber ran)
{
rnd = ran;
number = num;
serviceHigh = servHigh;
}
int teller::empty()
{
return isEmpty;
}
void teller::arriveacustomer(int arrtime)
{
isEmpty = 1;
time = arrtime + rnd.Random(serviceHigh - serviceLow + 1) + serviceLow;
if (servenow->Type == 0)
cout << "Time " << arrtime << ": customer " << servenow->num << " arrive teller " << number <<" .Serve over time : "<<time<< endl;
else
cout << "Time " << arrtime << ": customer " << servenow->num << "(VIP) arrive teller " << number <<" .Serve over time : "<<time<< endl;
}
void teller::free(int time)
{
if (servenow->Type == 1)
cout << "Time " << time << ": teller " << number << " serve over," << " customer " << servenow->num << "(VIP) leave" << endl;
else
cout << "Time " << time << ": teller " << number << " serve over," << " customer " << servenow->num << " leave" << endl;
time = 0;
isEmpty = 0;
servenow->leavetime = 0;
customer* tmp = servenow;
servenow = NULL;
//delete tmp;
}
int teller::leavetime()
{
return time;
}
void teller::flashleavetime(int nexttime)//队列为空时刷新柜台时间
{
time = nexttime;
}
class monitor//仅用于管理柜台
{
private:
teller* Tellers;
int numTeller;
public:
monitor(teller* tellers, int num)
{
Tellers = tellers;
numTeller = num;
}
int checktime();//检查下一个可服务时间
};
int monitor::checktime()
{
int lesstime = Tellers[0].leavetime();
int j = 0;
for (int i = 1; i < numTeller; i++)
{
if (Tellers[i].leavetime() < lesstime)
{
lesstime = Tellers[i].leavetime();
j = i;
}
}
return j;//返回柜台号,在柜台处查询信息
}
class alarm//设置时间//可考虑修改为结构体
{
public:
int nextTeller;
int nextArriveTime;
int nextLeaveTime;
int nextInsertTime;//需要插队的时间
customer* needInsertVip;//可能需要插队的顾客
customer* needInsertNormal;
int nextResponce;//下一个待处理的时间
int nextType;// -1 无, 0 顾客到达 ,1 顾客离开 ,2 需要插队
alarm(void);
void setnext();//刷新
};
alarm::alarm(void)
{
nextArriveTime = nextLeaveTime = 0;
nextResponce = -1;
nextType = -1;
nextTeller = 0;
needInsertVip = needInsertNormal = NULL;
nextInsertTime = MAX_TIME;
}
void alarm::setnext()//同一时间处理优先级为:顾客到达->顾客插队->顾客离开柜台。
{
if (nextArriveTime > nextLeaveTime)
{
if (nextInsertTime > nextLeaveTime)
{
nextResponce = nextLeaveTime;
nextType = 1;
}
else
{
nextResponce = nextInsertTime;
nextType = 2;
}
}
else
{
if (nextInsertTime >= nextArriveTime)
{
nextResponce = nextArriveTime;
nextType = 0;
}
else
{
nextResponce = nextInsertTime;
nextType = 2;
}
}
}
void initCustomer(customer* a, int time, int customNum, int maxWaitVip,int maxWaitNormal, RandomNumber rnd)//初始化一个顾客,生成id和类型,保存传入的时间以便后续计算总等待时间。
{
a->arrivetime = time;
a->leavetime = MAX_TIME;
a->next = NULL;
a->num = customNum;
a->startserve = MAX_TIME;
a->Type = a->num%2;
a->insert=0;
if (a->Type == 0)
{
a->wait = time + maxWaitNormal;
cout << "Time " << time << ": customer " << customNum << " arrive." << endl;
}
else
{
a->wait = time + maxWaitVip;
cout << "Time " << time << ": custome " << customNum << " (VIP) arrive." << endl;
}
}
int rndNext(RandomNumber rnd, int arrLow, int arrHigh, int time)//生成下一个出现客户的时间
{
return rnd.Random(arrHigh - arrLow + 1) + arrLow + time;
}
int main()
{
int simulationLength;
int numTellers;
int maxWaitVip,maxWaitNormal;
int arrivalLow, arrivalHigh;
int serviceLow, serviceHigh;
queue normalQueue;
RandomNumber rnd;
alarm aAlarm;
cout << "Enter the simulation time in minutes: ";
cin >> simulationLength;
cout << "Enter the number of normal tellers: ";
cin >> numTellers;
cout << "Enter the VIP maximum waiting time: ";
cin >> maxWaitVip;
cout << "Enter the normal customer maximum waiting time: ";
cin >> maxWaitNormal;
cout << "Enter the range of arrival times in minutes: ";
cin >> arrivalLow >> arrivalHigh;
cout << "Enter the range of service times in minutes: ";
cin >> serviceLow >> serviceHigh;
customer* first = new customer();
initCustomer(first, 0, 1, maxWaitVip,maxWaitNormal, rnd);//设置第一个顾客并插入对应队列
normalQueue.add(first);
teller* tellers = new teller[numTellers];
for (int i = 0; i < (numTellers); i++)
{
tellers[i].init(i, serviceHigh, serviceLow, rnd);
}
int customercount = 2;
int time = 0;
monitor tellermonitor(tellers, numTellers);
aAlarm.nextArriveTime = rndNext(rnd, arrivalLow, arrivalHigh, time);
normalQueue.leave();
tellers[aAlarm.nextTeller].servenow = first;
tellers[aAlarm.nextTeller].arriveacustomer(time);
aAlarm.nextTeller = tellermonitor.checktime();
aAlarm.nextLeaveTime = tellers[aAlarm.nextTeller].leavetime();
aAlarm.setnext();
time = aAlarm.nextResponce;
while (time <= simulationLength)
{
if (aAlarm.nextType == 0)//到达一个客户
{
customer* newCustomer = new customer;
initCustomer(newCustomer, time, customercount, maxWaitVip,maxWaitNormal, rnd);
normalQueue.add(newCustomer);
normalQueue.print();
if (aAlarm.needInsertVip == NULL && newCustomer->Type == 1)//目前未有闹钟客户
aAlarm.needInsertVip = newCustomer;
if (aAlarm.needInsertNormal == NULL && newCustomer->Type == 0)
aAlarm.needInsertNormal = newCustomer;
customercount += 1;
aAlarm.nextArriveTime = rndNext(rnd, arrivalLow, arrivalHigh, time);
}
else if (aAlarm.nextType == 1) //一个客户离开
{
if (tellers[aAlarm.nextTeller].servenow != NULL)//柜台不为空
tellers[aAlarm.nextTeller].free(time);
if (!normalQueue.isempty()) {
customer* cus = normalQueue.leave(); // 从普通队列中取出顾客
if (cus == aAlarm.needInsertVip)
aAlarm.needInsertVip = normalQueue.nextVIP(cus);
if (cus == aAlarm.needInsertNormal)
aAlarm.needInsertNormal = normalQueue.nextNormal(cus);
tellers[aAlarm.nextTeller].servenow = cus;
tellers[aAlarm.nextTeller].arriveacustomer(time);
}
else//队列为空
{
tellers[aAlarm.nextTeller].flashleavetime(aAlarm.nextArriveTime);
}
//设置下一个响应时间和柜台
aAlarm.nextTeller = tellermonitor.checktime();
aAlarm.nextLeaveTime = tellers[aAlarm.nextTeller].leavetime();
}
else if (aAlarm.nextType == 2)//有一个顾客要插队。
{
if (aAlarm.needInsertNormal != NULL || aAlarm.needInsertVip != NULL)
{
if (aAlarm.needInsertNormal == NULL)
{
cout << "Time " << time << ": customer " << aAlarm.needInsertVip->num << "(VIP) wait " << maxWaitVip << " ! INSERT!" << endl;
customer* tmp = normalQueue.nextVIP(aAlarm.needInsertVip);//插队的下一个客户即为需要关注的插队对象
normalQueue.insert(aAlarm.needInsertVip);//插队
aAlarm.needInsertVip = tmp;
}
else if (aAlarm.needInsertVip == NULL)
{
cout << "Time " << time << ": customer " << aAlarm.needInsertNormal->num << " wait " << maxWaitNormal << " ! INSERT!" << endl;
customer* tmp = normalQueue.nextNormal(aAlarm.needInsertNormal);//插队的下一个客户即为需要关注的插队对象
normalQueue.insert(aAlarm.needInsertNormal);//插队
aAlarm.needInsertNormal = tmp;
}
else if (aAlarm.needInsertNormal->wait < aAlarm.needInsertVip->wait)//需要插队的为普通客户
{
cout << "Time " << time << ": customer " << aAlarm.needInsertNormal->num << " wait " << maxWaitNormal << " ! INSERT!" << endl;
customer* tmp = normalQueue.nextNormal(aAlarm.needInsertNormal);//插队的下一个客户即为需要关注的插队对象
normalQueue.insert(aAlarm.needInsertNormal);//插队
aAlarm.needInsertNormal = tmp;
}
else if (aAlarm.needInsertNormal->wait >= aAlarm.needInsertVip->wait)
{
cout << "Time " << time << ": customer " << aAlarm.needInsertVip->num << "(VIP) wait " << maxWaitVip << " ! INSERT!" << endl;
customer* tmp = normalQueue.nextVIP(aAlarm.needInsertVip);//插队的下一个客户即为需要关注的插队对象
normalQueue.insert(aAlarm.needInsertVip);//插队
aAlarm.needInsertVip = tmp;
}
}
}
if (aAlarm.needInsertNormal == NULL && aAlarm.needInsertVip == NULL)
aAlarm.nextInsertTime = aAlarm.nextArriveTime;
else if (aAlarm.needInsertNormal == NULL)
aAlarm.nextInsertTime = aAlarm.needInsertVip->wait;
else if (aAlarm.needInsertVip == NULL)
aAlarm.nextInsertTime = aAlarm.needInsertNormal->wait;
else if ( aAlarm.needInsertNormal->wait < aAlarm.needInsertVip->wait)
aAlarm.nextInsertTime = aAlarm.needInsertNormal->wait;
else if (aAlarm.needInsertNormal->wait >= aAlarm.needInsertVip->wait)
aAlarm.nextInsertTime = aAlarm.needInsertVip->wait;
aAlarm.setnext();
time = aAlarm.nextResponce;
}
aAlarm.nextArriveTime = MAX_TIME;
while (time < MAX_TIME)//处理剩余客户
{
if (aAlarm.nextType == 1) //一个客户离开
{
if (tellers[aAlarm.nextTeller].servenow != NULL)//柜台不为空
tellers[aAlarm.nextTeller].free(time);
if (!normalQueue.isempty()) {
customer* cus = normalQueue.leave(); // 从普通队列中取出顾客
if (cus == aAlarm.needInsertVip)
aAlarm.needInsertVip = normalQueue.nextVIP(cus);
if (cus == aAlarm.needInsertNormal)
aAlarm.needInsertNormal = normalQueue.nextNormal(cus);
tellers[aAlarm.nextTeller].servenow = cus;
tellers[aAlarm.nextTeller].arriveacustomer(time);
}
else//队列为空
{
tellers[aAlarm.nextTeller].flashleavetime(MAX_TIME);
}
//设置下一个响应时间和柜台
aAlarm.nextTeller = tellermonitor.checktime();
aAlarm.nextLeaveTime = tellers[aAlarm.nextTeller].leavetime();
}
else if (aAlarm.nextType == 2)//有一个顾客要插队。
{
if (aAlarm.needInsertNormal != NULL || aAlarm.needInsertVip != NULL)
{
if (aAlarm.needInsertNormal == NULL)
{
cout << "Time " << time << ": customer " << aAlarm.needInsertVip->num << "(VIP) wait " << maxWaitVip << " ! INSERT!" << endl;
customer* tmp = normalQueue.nextVIP(aAlarm.needInsertVip);//插队的下一个客户即为需要关注的插队对象
normalQueue.insert(aAlarm.needInsertVip);//插队
aAlarm.needInsertVip = tmp;
}
else if (aAlarm.needInsertVip == NULL)
{
cout << "Time " << time << ": customer " << aAlarm.needInsertNormal->num << " wait " << maxWaitNormal << " ! INSERT!" << endl;
customer* tmp = normalQueue.nextNormal(aAlarm.needInsertNormal);//插队的下一个客户即为需要关注的插队对象
normalQueue.insert(aAlarm.needInsertNormal);//插队
aAlarm.needInsertNormal = tmp;
}
else if (aAlarm.needInsertNormal->wait < aAlarm.needInsertVip->wait)//需要插队的为普通客户
{
cout << "Time " << time << ": customer " << aAlarm.needInsertNormal->num << " wait " << maxWaitNormal << " ! INSERT!" << endl;
customer* tmp = normalQueue.nextNormal(aAlarm.needInsertNormal);//插队的下一个客户即为需要关注的插队对象
normalQueue.insert(aAlarm.needInsertNormal);//插队
aAlarm.needInsertNormal = tmp;
}
else if (aAlarm.needInsertNormal->wait >= aAlarm.needInsertVip->wait)
{
cout << "Time " << time << ": customer " << aAlarm.needInsertNormal->num << " wait " << maxWaitNormal << " ! INSERT!" << endl;
customer* tmp = normalQueue.nextNormal(aAlarm.needInsertNormal);//插队的下一个客户即为需要关注的插队对象
normalQueue.insert(aAlarm.needInsertNormal);//插队
aAlarm.needInsertNormal = tmp;
}
}
if (aAlarm.needInsertNormal == NULL && aAlarm.needInsertVip == NULL)
aAlarm.nextInsertTime = aAlarm.nextArriveTime;
else if (aAlarm.needInsertNormal == NULL)
aAlarm.nextInsertTime = aAlarm.needInsertVip->wait;
else if (aAlarm.needInsertVip == NULL)
aAlarm.nextInsertTime = aAlarm.needInsertNormal->wait;
else if (aAlarm.needInsertNormal->wait < aAlarm.needInsertVip->wait)
aAlarm.nextInsertTime = aAlarm.needInsertNormal->wait;
else if (aAlarm.needInsertNormal->wait >= aAlarm.needInsertVip->wait)
aAlarm.nextInsertTime = aAlarm.needInsertVip->wait;
}
aAlarm.setnext();
time = aAlarm.nextResponce;
}
delete[]tellers;
return 0;
}