Traté de construir un modelo simple con múltiples declaraciones 'con' como se muestra a continuación. Sin embargo, según la sangría, el resultado fue diferente. Por favor, hágame saber cuál es la regla clara de sangría.
import simpy
import random
class Pre_Define:
warmup_period = 1440
sim_duration = 14400
number_of_runs = 1 #3
n_edbed = 77
class Patients:
def __init__(self, p_id):
self.id = p_id
self.bed_name = ""
self.admission_decision = ""
def admin_decision(self):
admin_decision_prob = random.uniform(0, 1)
if admin_decision_prob <= 0.7:
self.admission_decision = "DIS"
else:
self.dmission_decision = "IU"
return self.admission_decision
class Model:
def __init__(self, run_number):
self.env = simpy.Environment()
self.pt_ed_q = simpy.Store(self.env )
self.pt_counter = 0
self.tg = simpy.Resource(self.env, capacity = 4)
self.physician = simpy.Resource(self.env, capacity = 4)
self.bed_clean = simpy.Store(self.env)
self.bed_dirty = simpy.Store(self.env)
self.IU_bed = simpy.Resource(self.env, capacity = 50)
self.bed_transporter = simpy.Resource(self.env, capacity = 10)
# self.bed_cleaner = simpy.Resource(self.env, capacity = 2)
self.run_number = run_number
def generate_beds(self):
for i in range(Pre_Define.n_edbed):
yield self.env.timeout(0)
yield self.bed_clean.put(f'bed{i}')
# print(self.bed_clean.items)
def generate_pt_arrivals(self):
while True:
self.pt_counter += 1
pt = Patients(self.pt_counter)
yield self.env.timeout(5)
self.env.process(self.ed_process(pt))
def clean_beds_process(self, cleaner_id):
while True:
bed = yield self.bed_dirty.get()
#print(f'{self.env.now:.2f} cleaner {cleaner_id} has started to clean bed {bed}')
# clean bed
yield self.env.timeout(50)
#print(f'{self.env.now:.2f} cleaner {cleaner_id} has finish cleaning bed {bed}')
# put bed in clean bed queue, loop to wait for next dirty bead
yield self.bed_clean.put(bed)
def ed_process(self, pt):
# process for treating a patient
#print(f'{self.env.now:.2f} patient {pt.id} has arrived')
with self.tg.request() as req:
yield req
yield self.env.timeout(10)
#print(f'{self.env.now:.2f} patient {pt.id} has been triaged')
bed = yield self.bed_clean.get()
pt.bed_name = bed
#print(f'{self.env.now:.2f} patient {pt.id} has a clean EU bed {bed}')
with self.physician.request() as req:
yield req
yield self.env.timeout(10)
pt.admin_decision()
#print(f'{self.env.now:.2f} patient {pt.id} has admission descesion of {pt.admission_decision}')
if pt.admission_decision == "DIS":
with self.IU_bed.request() as req:
print(f'{self.env.now:.2f} patient {pt.id} is waiting IU bed')
yield req
with self.bed_transporter.request() as transreq:
print(f'{self.env.now:.2f} patient {pt.id} is waiting transporter')
yield transreq
yield self.env.timeout(15)
dirty_bed_name = pt.bed_name
yield self.bed_dirty.put(dirty_bed_name)
print(f'{self.env.now:.2f} patient {pt.id} moved to IU and give up {dirty_bed_name}')
yield self.env.timeout(600)
print(f'{self.env.now:.2f} IU bed is available')
else:
# patient leaves EU
dirty_bed_name = pt.bed_name
#Bed_Mgmt.check_q(pt_id, self.pt_ed_q, self.bed_clean, self.bed_dirty, self.bed_cleaner)
yield self.bed_dirty.put(dirty_bed_name)
#print(f'{self.env.now:.2f} patient {pt.id} left EU giving up bed {dirty_bed_name}')
def run(self):
self.env.process(self.generate_pt_arrivals())
self.env.process(self.generate_beds())
# creating and starting two cleaners
for i in range(2):
self.env.process(self.clean_beds_process(i+1))
#self.env.run(until = Pre_Define.warmup_period + Pre_Define.sim_duration)
self.env.run(until = 650)
for run in range(Pre_Define.number_of_runs):
run_model = Model(run)
run_model.run()
print()
No hay error, pero el resultado fue diferente por sangría.
Por ejemplo, Caso1>
if pt.admission_decision == "DIS":
with self.IU_bed.request() as req:
print(f'{self.env.now:.2f} patient {pt.id} is waiting IU bed')
yield req
with self.bed_transporter.request() as transreq:
print(f'{self.env.now:.2f} patient {pt.id} is waiting transporter')
yield transreq
yield self.env.timeout(15)
dirty_bed_name = pt.bed_name
yield self.bed_dirty.put(dirty_bed_name)
print(f'{self.env.now:.2f} patient {pt.id} moved to IU and give up {dirty_bed_name}')
yield self.env.timeout(600)
print(f'{self.env.now:.2f} IU bed is available')
Caso2>
if pt.admission_decision == "DIS":
with self.IU_bed.request() as req:
print(f'{self.env.now:.2f} patient {pt.id} is waiting IU bed')
yield req
with self.bed_transporter.request() as transreq:
print(f'{self.env.now:.2f} patient {pt.id} is waiting transporter')
yield transreq
yield self.env.timeout(15)
dirty_bed_name = pt.bed_name
yield self.bed_dirty.put(dirty_bed_name)
print(f'{self.env.now:.2f} patient {pt.id} moved to IU and give up {dirty_bed_name}')
yield self.env.timeout(600)
print(f'{self.env.now:.2f} IU bed is available')
Caso3>
if pt.admission_decision == "DIS":
with self.IU_bed.request() as req:
print(f'{self.env.now:.2f} patient {pt.id} is waiting IU bed')
yield req
with self.bed_transporter.request() as transreq:
print(f'{self.env.now:.2f} patient {pt.id} is waiting transporter')
yield transreq
yield self.env.timeout(15)
dirty_bed_name = pt.bed_name
yield self.bed_dirty.put(dirty_bed_name)
print(f'{self.env.now:.2f} patient {pt.id} moved to IU and give up {dirty_bed_name}')
yield self.env.timeout(600)
print(f'{self.env.now:.2f} IU bed is available')
No estoy seguro de cómo sangrar después de "con"...
Solución del problema
el recurso se libera al final del código imputado. con cualquier "con", se llama cerrar al final de la sangría. El otro caso de uso común para "con" es la lectura de archivos o secuencias. Dado que la tienda de camas sucias es infinita, creo que los casos 1 y 2 funcionarían de la misma manera. La diferencia tecnológica está en el caso 1, el transportador se libera después de la yield self.env.timeout(15)
línea. mientras que en el caso 2 se libera después de la print(f'{self.env.now:.2f}.
declaración.... y en el caso 3 tanto la cama de IU como el transportador se liberan al final, manteniéndose el transportado durante el tiempo de espera (600)
Creo que el caso 1 es lo que quieres
No hay comentarios:
Publicar un comentario