1  #include <deque>
  2  #include <iostream>
  3  
  4  using namespace std;
  5  
  6  int rand_int(int a, int b)
  7  {
  8      return a + rand() % (b - a + 1);
  9  }
 10  
 11  double rand_double(double a, double b)
 12  {
 13      return a + (b - a) * rand() * (1.0 / RAND_MAX);
 14  }
 15  
 16  const int MIN_PROCESS_TIME = 2;
 17  const int MAX_PROCESS_TIME = 8;
 18  
 19  /**
 20      A typical customer.
 21      Customers arrive at random time,
 22      and take random time to process work.
 23  */
 24  class Customer
 25  {
 26  public:
 27      Customer(int at = 0);
 28      /**
 29         Return arrival time, set by constructor.
 30         @return arrival time
 31      */
 32      int get_arrival_time() const;
 33  
 34      /**
 35         Return process time, set randomly by constructor.
 36         @return process time
 37      */
 38      int get_process_time() const;
 39  
 40  private:
 41      int arrival_time;
 42      int process_time;
 43  };
 44  
 45  Customer::Customer(int at) :
 46      arrival_time(at),
 47      process_time(rand_int(MIN_PROCESS_TIME, MAX_PROCESS_TIME))
 48  {
 49  }
 50  
 51  int Customer::get_arrival_time() const
 52  {
 53      return arrival_time;
 54  }
 55  
 56  int Customer::get_process_time() const
 57  {
 58      return process_time;
 59  }
 60  
 61  /**
 62      Simulation of bank teller.
 63  */
 64  class Teller
 65  {
 66  public:
 67      Teller();
 68  
 69      /**
 70         @return true if teller is free to service customer
 71      */
 72      bool is_free() const;
 73  
 74      /**
 75         Updates the teller status.
 76         @param time the current time
 77      */
 78      void update(int time);
 79  
 80      /**
 81         Assign a teller to customer.
 82         @param c the customer
 83      */
 84      void add_customer(const Customer& c, int time);
 85  private:
 86      bool free;
 87      Customer customer;
 88      int start_time;
 89  };
 90  
 91  Teller::Teller()
 92  {
 93      free = true;
 94  }
 95  
 96  bool Teller::is_free() const
 97  {
 98      return free;
 99  }
100  
101  void Teller::update(int time)
102  {
103      if (free) return;
104      if (time > start_time + customer.get_process_time())
105         free = true;
106  }
107  
108  void Teller::add_customer(const Customer& c, int time)
109  {
110      free = false;
111      customer = c;
112      start_time = time;
113  }
114  
115  int main()
116  {
117      const int NUMBER_OF_TELLERS = 5;
118      const int NUMBER_OF_MINUTES = 60;
119  
120      const double ARRIVAL_RATE = 0.9;
121      double total_wait = 0;
122      int number_of_customers = 0;
123      deque<Teller> teller(NUMBER_OF_TELLERS);
124      deque<Customer> line;
125  
126      for (int time = 0; time < NUMBER_OF_MINUTES; time++)
127      {
128         if (rand_double(0, 1) < ARRIVAL_RATE)
129         {
130            line.push_back(Customer(time));
131         }
132  
133         for (int i = 0; i < NUMBER_OF_TELLERS; i++)
134         {
135            teller[i].update(time);
136            if (teller[i].is_free() && !line.empty())
137            {
138               Customer front_customer = line.front();
139               total_wait += (time - front_customer.get_arrival_time());
140               number_of_customers++;
141               teller[i].add_customer(front_customer, time);
142               line.pop_front();
143            }
144         }
145      }
146      cout << "average wait: " << (total_wait / number_of_customers) << "\n";
147      return 0;
148  }