📄 simulation.h
字号:
typedef LinkList EventList; //事件链表类型,定义为有序链表
EventList ev; //事件表
Event en; //事件(已开始理发或者还未纳入理发)
LinkQueue Q; //等候理发的顾客队列
QElemType customer; //顾客记录
int t2,t1,Totaltime,CustomerNum,OpenTime,OpenHour,OpenMinute,CloseTime,CloseHour,CloseMinute,k,m,CurrentChair,ShowTbl; //,,累计顾客逗留时间,顾客数,关门时间,,椅子数
float Totallength; //等候队伍长度
//---------------------一天工作初始化--------------------------------
void OpenForDay()
{
cout<<"******************************************************************"<<endl<<endl;
cout<<"新的一天开始了,今天也要加油干啊!"<<endl<<endl;
t1=t2=0;
Totaltime=0;
Totallength=0;
CustomerNum=0;
InitList(ev);
en.OccurTime=0;
en.NType=0;
OrderInsert(ev,en);
InitQueue(Q);
cout<<"首先请输入以下三项内容(均输入一个整数即可):"<<endl;
cout<<"1. 今天需要的椅子数:";
cin>>k;
while(k<=0)
{
cout<<"不想作生意了吗,椅子数怎么能比0小呢!请重新输入:";
cin>>k;
}
CurrentChair=k;
cout<<"2. 请按“时 分”的格式输入今天的开门时间::";
cin>>OpenHour>>OpenMinute;
while(OpenHour<0||OpenHour>24)
{
cout<<"时间输入不大对吧,请重新输入:";
cin>>OpenHour>>OpenMinute;
}
while(OpenMinute<0||OpenMinute>60)
{
cout<<"时间输入不大对吧,请重新输入:";
cin>>OpenHour>>OpenMinute;
}
OpenTime=OpenHour*60+OpenMinute;
cout<<"3. 请按“时 分”的格式输入今天的关门时间(一天按24小时计):";
cin>>CloseHour>>CloseMinute;
while(CloseHour<0||CloseHour>24)
{
cout<<"时间输入不大对吧,请重新输入:";
cin>>CloseHour>>CloseMinute;
}
while(CloseMinute<0||CloseMinute>60)
{
cout<<"时间输入不大对吧,请重新输入:";
cin>>CloseHour>>CloseMinute;
}
CloseTime=CloseHour*60+CloseMinute-OpenTime;
if(CloseTime<0)
{
cout<<"关门时间怎么可以比开门时间还早呢?";
CloseTime=0;
}
else
cout<<endl;
}
//--------------------处理顾客到达事件--------------------
void CustomerArrived1()
{
QElemType e1; //一个队列元素,表示一个排队中顾客
ElemType e; //一个链表元素,表示一个事件(理发或等待分配)
int durtime,intertime,R; //理发时间,下一个顾客到达时间间隔,随机数
CustomerNum++; //顾客数加一
R=rand();
durtime=12+R%40; //生成理发时间
intertime=2+R%10; //生成下一个顾客时间间隔
if(ShowTbl==1) //如果用户选择显示顾客到达时刻表,则打印之
{
cout<<" | Durtime:"<<durtime;
if(durtime>9)
{
cout<<" | Intertime:"<<intertime;
}
else
{
cout<<" | Intertime:"<<intertime;
}
if(intertime>9)
{
cout<<" |"<<endl;
}
else
{
cout<<" |"<<endl;
}
}
//------------------------------------------------------------------
//以下讲解以第一个顾客进入举例说明,其余雷同,
//需要注意,下一个顾客的到达时间在当前顾客进店时已经确定,
//所以有关第二个顾客的相关信息判断在第一个顾客进入时就该进行
//------------------------------------------------------------------
//初始化时en.occurtime==0表示第一个顾客进门时间,intertime表示第二个顾客到达的时间间隔
//所以经此操作后e.occurtime就表示第二个顾客到达时间
e.OccurTime=en.OccurTime+intertime;
//初始化时t1==0,所以现把第二个顾客到达时间赋值给t1
if(e.OccurTime>t1) t1=e.OccurTime;
//因为此时第一个顾客刚进入理发,第二个顾客还未到达,所以e.NType=0
e.NType=0;
//如果第二个顾客到达时还未关门,就将其纳入链表等待事件处理
if(e.OccurTime<CloseTime)
OrderInsert(ev,e);
if(CurrentChair>0)
{
//如果还有空椅子,就让第一个顾客开始理发,所以e.NType=1
e.NType=1;
//第一个顾客进入时间+第一个顾客理发时间
//即第一个顾客离开时间,如果大于t1(t1现在等于第二个顾客到达时间)就重新赋值
//保证t1一直等于需完成所有理发工作的最晚时间(在最后计算收尾时间时使用)
e.OccurTime=en.OccurTime+durtime;
if(e.OccurTime>t1) t1=e.OccurTime;
//将已开始理发的第一个顾客重新插入链表,注意此时状态NType已变为1
//之所以说重新插入,是因为在haircut.cpp主程序中调用时先执行delfirst将第一个顾客
//清除出链表,那时NType等于0,即非理发状态,这时在经过合理判断后重新插入,注意
//重新插入后不仅状态位NType改变,Occurtime值也发生了改变,清除时表示第一个顾客
//进门时间,重新插入后表示第一个顾客离开时间
OrderInsert(ev,e);
//今天总理发时间增加,椅子数减少
Totaltime+=durtime;
CurrentChair--;
}
else
{
//如果没有空椅子,就让第一个顾客开始排队
//记录第一个顾客的进门时间、理发时间,将顾客插入队列Q
e1.ArrivalTime=en.OccurTime;
e1.Duration=durtime;
EnQueue(Q,e1);
//今天总队伍长度增加
Totallength+=QueueLength(Q); //累计队长
}
}
void CustomerArrived2()
{
QElemType e1;
ElemType e;
int durtime,intertime;
CustomerNum++;
cout<<"Input durtime(理发所需时间): ";
cin>>durtime;
cout<<"Input intertime(顾客到达的时间间隔):";
cin>>intertime;
cout<<endl;
e.OccurTime=en.OccurTime+intertime;
if(e.OccurTime>t1) t1=e.OccurTime;
e.NType=0;
if(e.OccurTime<CloseTime)
OrderInsert(ev,e);
if(CurrentChair>0)
{
e.OccurTime=en.OccurTime+durtime;
if(e.OccurTime>t1) t1=e.OccurTime;
e.NType=1;
OrderInsert(ev,e);
Totaltime+=durtime;
CurrentChair--;
}
else
{
e1.ArrivalTime=en.OccurTime;
e1.Duration=durtime;
EnQueue(Q,e1);
Totallength+=QueueLength(Q);
}
}
void CustomerDeparture()
{
int Departuretime;
ElemType e;
//如果等待理发队列非空
if(!QueueEmpty(Q))
{
//让排队等候的第一个顾客起立,存入customer
DeQueue(Q,customer);
//刚离去的顾客en的离开时间+当前起立顾客的理发时间 得到起立顾客的离开时间
Departuretime=en.OccurTime+customer.Duration;
//如果该时间大于t2就重新赋值,保证t2表示最迟离开的顾客时间(在最后判断收尾时间时使用)
if(Departuretime>t2) t2=Departuretime;
//同样,因为起立顾客已开始理发,所以NType=1,同时Occurtime赋值为其离开时间
e.OccurTime=Departuretime;
e.NType=1;
OrderInsert(ev,e);
//总理发时间增加
Totaltime+=Departuretime-customer.ArrivalTime;
}
//如果没有排队等候的顾客,简单的将椅子数加一,返回haircut.cpp主调用程序继续循环
else
{
CurrentChair++;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -