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

📄 simulation.h

📁 理发馆问题。基于vc的模拟试验.包括试验设计文稿。
💻 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 + -