5.1 Simulation Model Code
The simulation code written by the group is run on Python. A brief overview of the steps conducted in the writing and implementation of the code is provided below:
Import code files which are used in the module.
Initiate the Random seed to ensure the same outcome every time.
Define the patient waiting queues from SimClasses to record the patient’s waiting for the regular bed and ICU bed.
Define the queues to record the patients that are already being treated.
Initiate the DTStat from SimClasses for collecting the time of different processes in the system.
In this section, the main components of the simulation model code are further explained. This includes the patient arrival method (non-stationary method), the process for removing patients from the queues for both ICU and regular beds, and simulation loop.
Non-stationary input
load data
Arate = lambda rate by weeks / 7
MaxRate = max(Arate)
def NSRate(current clock):
if last period <= current < future period:
return Arate[lambda rate]
def NSPP(random seed):
possible arrival time = current clock + interArrival time ~ Expon(1/ MaxRate)
while possible arrival time < run length and random uniform >= NSRate(possible arrival time)
possible arrival time = current clock + interArrival time ~ Expon(1/ MaxRate)
nspp = possible arrival time - current time
return nspp non stationary poisson process
def Arrival():
Number of Arrival += 1
InterArrival time = NSPP(1)
SimFunctions.Schedule(Calendar, “Arrival”, InterArrival time)
New NewPatient = SimClasses.Entity()
if random probability > 0.06:
if regular bed available:
# of regular bed - 1
bed time ~ lognormal()
SimFunctions.SchedulePlus(Calendar, “EndOfRegular”, bed time, NewPatient)
else:
if wait in RegularQueue == 0:
out of Bed After Days = current clock
RegularQueue record outofBedAfterDays
else:
if ICU bed available:
# of ICU bed - 1
Bed time ~ lognormal()
SimFunctions.SchedulePlus(Calendar, “EndOfICU”, bed time, NewPatient)
else:
if wait in ICUQueue == 0:
out of Bed After Days = current clock
ICUQueue record outofBedAfterDays
def EndOfRegular(Departing Patient):
if patient transfer or random probability > 0.1562:
if patient in RegularQueue:
patient = RegularQueue.pop()
Regular wait time recorded = Current time - patient.create time
if patient not transferred:
Bed time ~ lognormal()
SimFunctions.SchedulePlus(Calendar, “EndOfRegular”, bed time, patient)
if random probability > 0.1765:
# patient alive += 1
else:
# patient die += 1
else:
Bed time ~ lognormal()
SimFunctions.SchedulePlus(Calendar, “EndOfRegular”, bed time, patient)
if random probability > 0.4316:
# patient die += 1
else:
# patient alive += 1
else:
# of available regular bed + 1
else:
Departing patient Transferred
Bed time ~ Gamma()
SimFunctions.SchedulePlus(Calendar, “EndOfRegular”, bed time, Departing patient)
if random probability > 0.0787:
# patient die += 1
else:
# patient alive += 1
def EndOfICU(Departing Patient):
if patient transfer or random probability > 0.6:
if patient in ICUQueue:
patient = ICUQueue.pop()
ICU wait time recorded = Current time - patient.create time
if patient not transferred:
Bed time ~ lognormal()
SimFunctions.SchedulePlus(Calendar, “ICU”, bed time, patient)
if random probability > 0.0787:
# patient die += 1
else:
# patient alive += 1
else:
Bed time ~ lognormal()
SimFunctions.SchedulePlus(Calendar, “EndOfICU”, bed time, patient)
if random probability > 0.4316:
# patient die += 1
else:
# patient alive += 1
else:
# of available ICU bed + 1
else:
Departing patient Transferred
Bed time ~ lognormal()
SimFunctions.SchedulePlus(Calendar, “EndOfICU”, bed time, Departing patient)
if random probability > 0.1765:
# patient alive += 1
else:
# patient die += 1
for reps in 10:
if event type = “Arrival”:
Arrival()
while Next event type != “EndSimulation”:
Calendar.Remove()
if Next event type = “Arrival”:
Arrival()
elif Next event type = “EndOfRegular”:
EndOfRegular(object)
elif Next event type = “EndOfICU”:
EndOfICU(object)
Calculate mean and Confidence Interval
5.2 Model Validation
A typical hospital in the US averages 3 hours in wait time for patient admittance into the ED. For hospital admittance to a regular bed, the wait time is significantly shorter and averages around 1.5 hours [9]. During COVID-19, these numbers increased dramatically as COVID patients occupied many hospital beds in large numbers and for longer hospital stays than those with other illnesses. Hospitals during the peak of COVID-19 regularly began each day at more than 100% of their hospital bed capacity [10]. However, there is not a lot of specific data on what wait times looked like for patients who arrived at the hospital looking for a bed. This is because if patients who were worried about their health encountered hospitals at full capacity, similar to the long wait times resulting from the simulation model, they would try a different hospital location or would enter the hospital without a bed at overcapacity. In these cases, hospitals would create makeshift hospital beds. Some states, such as Colorado, even allowed hospitals to turn away patients during COVID-19 surges. For this reason, there was no accurate data that the group could find about patient hospital wait times to compare with the simulation modeling results. For this reason, to validate the model, the group used patient arrival rates to confirm that the model is predictive under the conditions of its intended use.
In the data provided, patient arrivals per day fluctuated but the total arrivals to the system over the period that the data was collected reached 4,798. In the simulation model, as can be seen later in the report, the arrival rate for patients was around 4,700 patients in total, fluctuating slightly with each replication. Because the only data was not provided is the number of resources that led to the arrival number will be the only result that will not be changed in the simulation. Since both of these arrivals are close to each other, the group can validate that the model is working as intended.
5.3 Model Verification
In order to verify that the simulation code is accurate, the group used a more simple queueing network (Figure 2) to represent the more complex simulation model. In the queueing network, there are 2 arrival times representing patient arrivals to ICU beds and patient arrivals to regular impatient beds. The patients who arrive at the ICU have probability p1 of death, p2 of recovery and discharge, and 1-(p1+p2) of transfering to a regular impatient bed. The patients who arrive at the regular impatient beds have probability p4 of death, p3 of recovery and discharge, and 1-(p3+p4) of transfering to a regular impatient bed.
Figure 8. Queueing Network
The calculation for the arrivals for each of the 4 stations (ICU, Regular Impatient Beds, Death, and Recovery) is shown below using the probabilities found from the data (Calculations 1) and the initial arrival rates (1) into triage. The initial arrival rates were calculated by adding up the number of patients who entered into the ICU beds upon arrival or the Regular Impatient Beds upon arrival and dividing by the number of days over which these arrivals occurred (143 days). Using this method, it was found that the arrival rate is 33.5 patients/day. However, this arrival rate is greater than the service times for both regular and ICU beds. This means that the queueing system is in fact unstable and p<1. Lowering the arrival rate will make the queueing system more stable. To ensure the system is stable in this simplified example, the arrival rate is lowered to 10 patients/day.
Calculations 1. Queuing Network Calculations
Since the arrivals into the regular beds is by far greater than the ICU beds, the wait time in the queue calculated for regular beds is a lot greater. However, these calculations ignore the number of beds available for the ICU vs regular beds. Since the ICU has a much smaller capacity than the regular beds, this means that the wait time in the queue will actually be a lot greater than only 1.76 hours.