队列应用之售票窗口问题_legend

来源:互联网 发布:pr制作淘宝主图视频 编辑:程序博客网 时间:2024/04/29 10:06


售票口问题:

(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)效果图:


0 0