Doctors' Office Simulation
Package

We model the flow of patients through a doctors' office. Assume there are some number of doctors associated with a given doctors' office. Also, there is a receptionist. Suppose further that there are some number of patients that are serviced by the doctors' office.

All well patients become sick eventually. When that happens, they pay a visit to the doctors' office. The doctors' office consists of a waiting room with sick patients and a pool of doctors to serve them. The waiting room and the doctor pool are both managed by a receptionist. Patients in the waiting room are waiting to be served by doctors and doctors in the doctor pool are "available" to serve patients. The office system functions as follows:

  1. When a patient arrives at the doctors' office, he or she immediately enters the waiting room.
  2. At any moment, as long as there are doctors in the doctor pool and patients in the waiting room, and as long as new arrivals are no longer being processed, patients in the waiting room are paired with doctors in the doctor pool in first-come-first-serve order.
  3. When a patient and doctor are paired, they remain paired for some random period of time, determined by a mean pair time drop-down input. A paired doctor is unavailable. After that period elapses, the doctor is returned to the doctor pool to become available again, and the patient is sent home with a new time to becoming sick which is a random number determined from the mean sick time drop-down input.
  4. The patient remains at home for that period of time, then returns to the doctors' office for treatment.
It is necessary to determine how many doctors are needed to staff the office to keep the average wait time of patients below a specified minimum. We will run several simulations to get the answer which will appear as a graph of waiting time vs. the number of doctors. The simulation will be controlled by two additional parameters: the number of iterations (that is, events processed) and the number of people served by the office. Both parameters are set via drop-down input. Simulations are run for a number of doctors from 1 to 15, the wait time computed for each, and plotted.

Implementation Considerations:

Construct Patient, Doctor, and Receptionist classes containing all the usual information associated with those persons such as name and address.

Construct an EventManager class to manage the occurrence of events (any change is considered an event). Thus, an object of the EventManager class called, say event_manager, should maintain an event-list which containing a listing of future events, ordered by the time to occurrence. The event_manager drives the simulation by pulling next events off the event-list and making corresponding changes to the doctor pool and waiting room. Smooth operation of event_manager requires a priority list which is a small generalization of the List class discussed earlier. Priority lists differ from ordinary lists by one method called insert which places an object into the list in its correct position based on some attribute value. In this case the attribute value is time to occurrence. One other requirement of event_manager is construction of an Event class from which event objects are created. Event objects are carried in the event-list and make available the time-to-occurrence attribute so they can be correctly positioned in the event-list when they are inserted.

The discussion of the EventManager class suggests using the List class we have already considered and deriving from it the Priority-List or PList class which adds the insert method.

Here is what the driver function might look like:

   public void actionPerformed (ActionEvent evt) {
      double sickMean=0, pairMean=0;
      int m=0, npat=0;
      if (gt != null) gt.dispose();

      m = Integer.parseInt((String)iter.getSelectedItem());
      npat = Integer.parseInt((String)pats.getSelectedItem());
      sickMean = Integer.parseInt((String)sick.getSelectedItem());
      pairMean = Integer.parseInt((String)pair.getSelectedItem());
      
      EventManager em = new EventManager(sickMean, pairMean);

      int x[] = new int[20];
      int y[] = new int[20];
      int ymax = 0;
      for (int i=1 ; i < 16 ; i++) { // number of doctors
	 for (int k=0 ; k < i ; k++) em.addDoctorToPool(new Doctor());
	 for (int k=0 ; k < npat ; k++) em.addPatientSickEvent(new Patient());
	 x[i] = i;
	 y[i] = (int)em.runSim(m);
	 if (y[i] > ymax) ymax = y[i];
	 em.reset();
      }

      gt = new GraphFrame();
      gt.setSize(500,500);
      gt.setVisible(true);
      gt.setGraph(20, 1.1*ymax);
      for (int i=1 ; i < 15 ; i++) gt.drawLine(x[i],y[i],x[i+1],y[i+1]);
   }