-2

I'm using SimPy library for relatively simple hospital simulation. There are receptionists, nurses, acu and ed doctors. For each of them I assign the timeout. The point is to collect timeouts for each entity that visits patient. Then for each run_simulation I count mean value of these timeouts. And lastly in Trial_Results_Calculator class I get mean value of all timeout for all entities for certain amount of runs. Also there is an possibility for patient get to acu 20%.

The problem is with output for Mean Queueing Time for ACU Doctor over Trial : 1123.91 and Mean Queueing Time for ED Doctor over Trial : 791.31.

The values should be 3-4 times less for both mean queueing times.

import csv

import simpy
import pandas as pd
import random


class g:
    mean_inter_arrival = 8
    mean_registration = 2
    mean_triage = 5
    mean_ED_Assessment = 30
    mean_ACU_Assessment = 60
    prob_to_ACU = 0.2
    receptionists = 1
    nurses = 2
    ED_Doctors = 2
    ACU_Doctors = 1
    warm_up = 24*60
    run_time = 48*60
    run_times = 1


class Patient:
    def __init__(self, p_id):
        self.p_id = p_id
        self.q_time_receptionist = 0
        self.q_time_nurse = 0
        self.q_time_acu_doctor = float("nan")
        self.q_time_ed_doctor = float("nan")
        self.prob_to_acu = g.prob_to_ACU
        self.go_to_acu = False
        if random.random() <= self.prob_to_acu:
            self.go_to_acu = True

class Hospital_Model:
    def __init__(self, run_number):
        self.env = simpy.Environment()
        self.patient_counter = 0

        self.receptionist = simpy.Resource(self.env, capacity=g.receptionists)
        self.nurse = simpy.Resource(self.env, capacity=g.nurses)
        self.acu_doctor = simpy.Resource(self.env, capacity=g.ACU_Doctors)
        self.ed_doctor = simpy.Resource(self.env, capacity=g.ED_Doctors)

        self.mean_q_time_receptionist = 0
        self.mean_q_time_nurse = 0
        self.mean_q_time_acu_doctor = 0
        self.mean_q_time_ed_doctor = 0

        self.run_number = run_number

        self.results_df = pd.DataFrame()
        self.results_df["P_ID"] = []
        self.results_df["Q_Time_Receptionist"] = []
        self.results_df["Q_Time_Nurse"] = []
        self.results_df["Q_Time_ACU_Doctor"] = []
        self.results_df["Q_Time_ED_Doctor"] = []
        self.results_df.set_index("P_ID", inplace=True)

    def patient_arrival(self):
        while True:
            self.patient_counter += 1
            patient = Patient(self.patient_counter)

            self.env.process(self.attend_hospital(patient))

            sampled_interval = random.expovariate(1.0/g.mean_inter_arrival)
            yield self.env.timeout(sampled_interval)

    def attend_hospital(self, patient):
        start_q_receptionist = self.env.now

        with self.receptionist.request() as req:
            yield req

            end_q_receptionist = self.env.now

            patient.q_time_receptionist = end_q_receptionist - start_q_receptionist

            sampled_dur_wait = random.expovariate(1.0 / g.mean_registration)
            yield self.env.timeout(sampled_dur_wait)

        start_q_nurse = self.env.now

        with self.nurse.request() as req:
            yield req

            end_q_nurse = self.env.now

            patient.q_time_nurse = end_q_nurse - start_q_nurse

            sampled_dur_wait = random.expovariate(1.0 / g.mean_triage)
            yield self.env.timeout(sampled_dur_wait)

        if patient.go_to_acu:
            start_q_acu_doctor = self.env.now

            with self.acu_doctor.request() as req:
                yield req

                end_q_acu_doctor = self.env.now

                patient.q_time_acu_doctor = end_q_acu_doctor - start_q_acu_doctor

                sampled_dur_wait = random.expovariate(1.0 / g.mean_ACU_Assessment)
                yield self.env.timeout(sampled_dur_wait)

        else:
            start_q_ed_doctor = self.env.now

            with self.ed_doctor.request() as req:
                yield req

                end_q_ed_doctor = self.env.now

                patient.q_time_ed_doctor = end_q_ed_doctor - start_q_ed_doctor

                sampled_dur_wait = random.expovariate(1.0 / g.mean_ED_Assessment)
                yield self.env.timeout(sampled_dur_wait)

        if self.env.now > g.warm_up:
            df_add = pd.DataFrame({"P_ID": [patient.p_id],
                                   "Q_Time_Receptionist": [patient.q_time_receptionist],
                                   "Q_Time_Nurse": [patient.q_time_nurse],
                                   "Q_Time_ACU_Doctor": [patient.q_time_acu_doctor],
                                   "Q_Time_ED_Doctor": [patient.q_time_ed_doctor]})
            self.results_df = pd.concat([self.results_df, df_add], axis=0, join='outer')

    def calculate_mean_q_time(self):
        self.mean_q_time_receptionist = self.results_df["Q_Time_Receptionist"].mean()
        self.mean_q_time_nurse = self.results_df["Q_Time_Nurse"].mean()
        self.mean_q_time_acu_doctor = self.results_df["Q_Time_ACU_Doctor"].mean()
        self.mean_q_time_ed_doctor = self.results_df["Q_Time_ED_Doctor"].mean()

    def write_run_results(self):
        with open("trial_results_2.csv", "a") as f:
            writer = csv.writer(f, delimiter=",")
            results_to_write = [self.run_number,
                                self.mean_q_time_receptionist,
                                self.mean_q_time_nurse,
                                self.mean_q_time_acu_doctor,
                                self.mean_q_time_ed_doctor]
            writer.writerow(results_to_write)

    def run(self):
        self.env.process(self.patient_arrival())
        self.env.run(until=g.run_time+g.warm_up)
        self.calculate_mean_q_time()
        self.write_run_results()


class Trial_Results_Calculator:
    def __init__(self):
        self.trial_results_df = pd.DataFrame()

    def trial_results(self):
        print("TRIAL RESULTS")
        print("_____________")

        self.trial_results_df = pd.read_csv("trial_results_2.csv")
        trial_mean_q_time_receptionist = self.trial_results_df["Mean_Q_Time_Receptionist"].mean()
        trial_mean_q_time_nurse = self.trial_results_df["Mean_Q_Time_Nurse"].mean()
        trial_mean_q_time_acu_doctor = self.trial_results_df["Mean_Q_Time_ACU_Doctor"].mean()
        trial_mean_q_time_ed_doctor = self.trial_results_df["Mean_Q_Time_ED_Doctor"].mean()

        print(f"Mean Queueing Time for Receptionist over Trial : {round(trial_mean_q_time_receptionist, 2)}")
        print(f"Mean Queueing Time for Nurse over Trial : {round(trial_mean_q_time_nurse, 2)}")
        print(f"Mean Queueing Time for ACU Doctor over Trial : {round(trial_mean_q_time_acu_doctor, 2)}")
        print(f"Mean Queueing Time for ED Doctor over Trial : {round(trial_mean_q_time_ed_doctor, 2)}")


with open("trial_results_2.csv", "w") as f:
    writer = csv.writer(f, delimiter=",")
    column_headers = ["Run",
                      "Mean_Q_Time_Receptionist",
                      "Mean_Q_Time_Nurse",
                      "Mean_Q_Time_ACU_Doctor",
                      "Mean_Q_Time_ED_Doctor"]
    writer.writerow(column_headers)

for run in range(g.run_times):
    print(f"Run {run} of {g.run_times}")
    hospital = Hospital_Model(run)
    hospital.run()
    print()

my_trial_results = Trial_Results_Calculator()
my_trial_results.trial_results()

I got the code from this tutorial: "https://www.youtube.com/watch?v=QV-pJnKrGuc&ab_channel=HSMA"

Random Davis
  • 6,662
  • 4
  • 14
  • 24
WizzVard
  • 1
  • 1
  • On what basis do you state "The values should be 3-4 times less for both mean queueing times"? Do you have analytically derived results that you are comparing to (in which case, why are you simulating)? – pjs Aug 29 '23 at 17:41
  • I am comparing with video results in the end of the video, with the same amount of receptionists = 1 nurses = 2 ED_Doctors = 2 ACU_Doctors = 1 results for ed and acu doctors are 3-4 times less than mine – WizzVard Aug 29 '23 at 18:02
  • Are you comparing a single replication? Queueing systems are subject to very high degrees of variation if you have high traffic intensities. – pjs Aug 29 '23 at 18:04
  • I mean I did 100 runs, and none of these runs showed ed or acu doctors values lower than 400(that is 3 times larger then value in the video). My wrong mean values is around 1000 time units. – WizzVard Aug 29 '23 at 18:11
  • I suggest you review and double-check your code implementation to ensure no mistakes were made when following the tutorial, such as typing errors, incorrect assignments, or different logic order. Comparing your code line by line with the tutorial may help spot any discrepancies. And, **very important**: make sure you are using the same version of the SimPy library and other dependencies as in the tutorial. Sometimes, updates in the libraries might cause changes in the results due to the differences in how the calculations and processes are handled. – Random Davis Aug 29 '23 at 18:37
  • Also, providing a concise and focused question together with the necessary context solely within the post would be more in line with the site guidelines. Relying on a _90-minute-long video_ for context could potentially severely limit the number of people willing to engage with and help you on this platform. – Random Davis Aug 29 '23 at 18:39

0 Answers0