售票口问题:
(1)背景:银行窗口问题或者售票口问题:
(1.1)顾客只能排一队。即只有一个队列
(1.2)有多个窗口,每个窗口给每个顾客的平均服务时间为120s;
某个窗口空闲则队头的顾客不需排队。若每个窗口均不闲,则队头顾客需要排队。
(1.3)每隔15s就有一个新的顾客排队。
(1.4)根据每个顾客的平均服务时间来求得开几个窗口合适。
总服务时间/顾客数量。越小越好。
(2)代码实现:
#include <iostream>
using namespace std;
//#define DEBUG
/*顾客类型,包含到达窗口时间,离开窗口时间两个数据成员*/
class CustomerType{
private:
int arrivalTime;/*顾客到达时间,不是到达窗口时间*/
int leaveTime;/*顾客离开窗口时间*/
public:
/*构造函数,初始化数据成员*/
CustomerType(int arrive){
arrivalTime=arrive;
leaveTime=0;
}
CustomerType(){
arrivalTime=0;
leaveTime=0;
}
/*拷贝构造*/
CustomerType(CustomerType& customer){
arrivalTime=customer.getArrivalTime();
leaveTime=customer.getLeaveTime();
}
int getArrivalTime(){
return arrivalTime;
}
void setArrivalTime(int arrive){
arrivalTime=arrive;
}
int getLeaveTime(){
return leaveTime;
}
void setLeaveTime(int leave){
leaveTime=leave;
}
int spendTime(){
return (leaveTime-arrivalTime);
}
};
typedef CustomerType ElemType;
/*队列,顾客队列*/
class SeQueueType{
public:
int maxSize;
int front;
int rear;
ElemType * array;
public:
SeQueueType(int size){
maxSize=size;
array=new ElemType[maxSize];
front=0;
rear=0;
}
~SeQueueType(){
delete []array;
}
bool isEmpty(){
if(front==rear)
return true;
return false;
}
bool isFull(){
if((rear+1)%maxSize==front)
return true;
return false;
}
bool push(ElemType elem){
if(isFull()) return false;
array[rear]=elem;
rear=(rear+1)%maxSize;
return true;
}
bool pop(ElemType & elem){
if(isEmpty()) return false;
elem=array[front];
front=(front+1)%maxSize;
return true;
}
bool getFront(ElemType & elem){
if(isEmpty()) return false;
elem=array[front];
return true;
}
int length(){
return (rear-front+maxSize)%maxSize;
}
};
class WindowType{
public:
static int serviceTime_perCustom;/*每个顾客到达窗口与离开窗口的平均时间为120s*/
static int max_windows;/*最大的窗口数量*/
static int max_customers;/*最多的顾客*/
public:
void main();
};
int WindowType::serviceTime_perCustom=120;
int WindowType::max_customers=100;
int WindowType::max_windows=10;
void WindowType::main(){
CustomerType customer;
SeQueueType* customerQueue=new SeQueueType(max_customers+3);
int* serviceTime_winArray=new int[max_windows];
/*serviceTIme_winArray[i]表示i号窗口服务完上一个顾客后的总的服务时间*/
int totalTime;/*100个人被n个窗口服务完所需要的总时间*/
int averageTime;/*平均每个人的花费时间*/
int leaveTime;/*离开时间*/
int num_win;
for( num_win=0;num_win<max_windows;num_win++){
/*num_win表示每次模拟用了多少个窗口*/
for(int i=0;i<num_win;i++){
serviceTime_winArray[i]=0;/*开了num_win个窗口,初始化每个窗口的服务服务时间为0*/
}
#ifdef DEBUG
cout<<"当前窗口数为: "<<num_win+1<<" ,顾客均有入队 "<<endl;
#endif
for(int j=1;j<=max_customers;j++){
CustomerType customer2(j*15);
customerQueue->push(customer2);
}/*100个顾客进队列*/
totalTime=0;/*每次模拟num_win个窗口,初始化为0*/
while( !(customerQueue->isEmpty()) ){
for(int j=0;j<=num_win;j++){
if(!customerQueue->isEmpty()){
if(j==num_win)
j=0;/*队列中顾客数量大于窗口数。*/
customerQueue->pop(customer);
if(customer.getArrivalTime()>serviceTime_winArray[j]){
/*到达时间晚于j号窗口的服务时间,则无需等待*/
leaveTime=customer.getArrivalTime()+serviceTime_perCustom;
/*离开时间=每个顾客的平均服务时间+到达时间*/
}
else{
leaveTime=serviceTime_perCustom+serviceTime_winArray[j];
/*离开窗口时间=每个顾客服务时间+上一个顾客被服务完的时间*/
}
customer.setLeaveTime(leaveTime);
serviceTime_winArray[j]=leaveTime;/*更新该顾客被服务完后的窗口时间*/
totalTime+=customer.spendTime();/*加上该顾客花费的时间*/
}else break;
}
}/*end of while*/
averageTime=totalTime/max_customers;
cout<<"售票窗口数量 : "<<num_win+1<<endl;
cout<<"每个顾客的平均服务时间 :"<<averageTime<<endl;
cout<<"------------"<<endl;
}
}
int main()
{
WindowType window;
window.main();
cout << "Hello world!" << endl;
return 0;
}
(3)效果图: