如果我在需要时使用 'env.process()' 会怎样?
What happens if I using 'env.process()' whenever I need it?
我只想在必要时使用床清洁器。如下代码所示,没有出现错误,但结果不准确。增加或减少清洁器数量应该会改变结果,但无论清洁器数量如何变化,结果都是相同的。
也许我可以猜到,每当我使用 'env.process()' 时,“self.bed_cleaner”都会被重置。所以,清洁工总是闲着……但我不确定。
你觉得我不明白什么?请帮助我,我可以正确地进行实验。
import simpy
import random
class Pre_define:
ed_bed_cleaning_request = True
class Patients:
def __init__(self, p_id):
self.id = p_id
self.edbed_name = ""
self.iubed_name = ""
self.admission_decision = ""
self.wtime_bed_NotClean = float("nan")
def admin_decision(self):
if (self.id % 2) == 0: # even dis, else IU 50%
self.admission_decision = "DIS"
else:
self.admission_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.edbed_clean = simpy.Store(self.env, capacity = 4)
self.iubed_clean = simpy.Store(self.env, capacity = 4)
self.bed_dirty = simpy.Store(self.env, capacity = 8)
self.bed_cleaner = simpy.Resource(self.env, capacity = 1)
def generate_beds(self):
for i in range(4):
yield self.env.timeout(0)
yield self.edbed_clean.put(f'edbed{i}')
yield self.iubed_clean.put(f'iubed{i}')
def generate_pt_arrivals(self):
while True:
pt = Patients(self.pt_counter)
yield self.env.timeout(5)
self.env.process(self.process(pt))
self.pt_counter += 1
def clean_beds_process(self, pt):
bed = yield self.bed_dirty.get()
while True:
if (Pre_define.ed_bed_cleaning_request == True and bed[:2] == 'ed') or (Pre_define.ed_bed_cleaning_request == False and bed[:2] == 'iu'):
with self.bed_cleaner.request() as bedreq:
yield bedreq
yield self.env.timeout(30)
if bed[:2] == 'ed':
yield self.edbed_clean.put(bed)
else:
yield self.iubed_clean.put(bed)
break
elif (Pre_define.ed_bed_cleaning_request == False and bed[:2] == 'ed') or (Pre_define.ed_bed_cleaning_request == True and bed[:2] == 'iu'):
with self.bed_cleaner.request() as bedreq:
yield bedreq
yield self.env.timeout(30)
if bed[:2] == 'ed':
yield self.edbed_clean.put(bed)
else:
yield self.iubed_clean.put(bed)
else:
break
def process(self, pt):
with self.tg.request() as req:
yield req
yield self.env.timeout(10)
if self.edbed_clean.items == [] and self.bed_dirty.items != []:
Pre_define.ed_bed_cleaning_request = True
self.env.process(self.clean_beds_process(pt)) # =========> This part I use env.process() for call cleaner
elif self.edbed_clean.items == [] and self.bed_dirty.items == []:
self.env.process(self.clean_beds_process(pt))
Pre_define.ed_bed_cleaning_request = True
else:
Pre_define.ed_bed_cleaning_request = True
edbed = yield self.edbed_clean.get()
pt.edbed_name = edbed
pt.admin_decision()
if pt.admission_decision != "DIS":
if self.iubed_clean.items == [] and self.bed_dirty.items != []:
Pre_define.ed_bed_cleaning_request = False
self.env.process(self.clean_beds_process(pt)) # =========> This part I use env.process() for call cleaner
elif self.iubed_clean.items == [] and self.bed_dirty.items == []:
self.env.process(self.clean_beds_process(pt))
Pre_define.ed_bed_cleaning_request = False
else:
Pre_define.ed_bed_cleaning_request = False
iubed = yield self.iubed_clean.get()
pt.iubed_name = iubed
dirty_edbed_name = pt.edbed_name
yield self.bed_dirty.put(dirty_edbed_name)
yield self.env.timeout(60) # IU bed occupied time
dirty_iubed_name = pt.iubed_name
yield self.bed_dirty.put(dirty_iubed_name)
else:
dirty_bed_name = pt.edbed_name
yield self.bed_dirty.put(dirty_bed_name)
def run(self):
self.env.process(self.generate_beds())
self.env.process(self.generate_pt_arrivals())
self.env.run(until = 200)
run_model = Model(0)
run_model.run()
病人只有干净的床。 EU 和 IU 床都在清洁中。两种类型的脏床被放入一个共同的床清洁队列中。清洁工足够聪明,可以将 eu 床放入 eu clean bed 队列,将 iu 床放入 clean iu bed 队列。还减少了 iu 处理时间,使脏 iu 床更快地出现在日志中。 Bed 现在是具有 ID 和类型的 class。否则这是之前几个问题中的同一个程序
"""
Hospital bed sim 3
Patient arrives,
gets trianged,
gets a clean eu bed from clean eu bed queue
leaves eu bed which is queued for cleaning beds
if admitted get iu bed from clean iu bed queue
gets treated
leaves, puting the iu bed in the queue for cleaning.
bed cleaners wait for beds to show up in cleaning queue
both eu and iu beds are in the same queue
after cleaning a bed it is put into is clean bed queue
(clean eu beds go to the clean eu queue, clean iu beds go to the clean iu queue)
Programer Michael R. Gibbs
"""
import simpy
import random
class Pre_Define:
warmup_period = 1440
sim_duration = 14400
number_of_runs = 1 #3
eu_beds= 77
iu_beds=50
class Bed():
"""
Hosptial beds, can have two types emergency (eu) and inpatiient (iu)
"""
def __init__(self, id, type):
self.id = id
self.type = type
class Patients:
"""
enity model is processing
uses beds
"""
def __init__(self, p_id):
self.id = p_id
self.bed = None
self.admission_decision = ""
def admin_decision(self):
"""
decides if a eu patient becmes a iu patient
"""
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.iu_bed_clean = simpy.Store(self.env)
self.eu_bed_clean = simpy.Store(self.env)
self.bed_dirty = simpy.Store(self.env)
self.run_number = run_number
def generate_beds(self):
"""
create the clean eu and iu beds
"""
self.eu_bed_clean.items = [Bed(i+1, "EU") for i in range(Pre_Define.eu_beds)]
self.iu_bed_clean.items = [Bed(i+1, "IU") for i in range(Pre_Define.iu_beds)]
def generate_pt_arrivals(self):
while True:
self.pt_counter += 1
pt = Patients(self.pt_counter)
#yield self.env.timeout(1/7)
yield self.env.timeout(5)
self.env.process(self.ed_process(pt))
def clean_beds_process(self, cleaner_id):
"""
contious process for cleaning beds
feeds off of the dirty bed queue
if the queue is empty, will wait
until a bed is added to the queue.
Clean beds are returned to the clean bed queue
This process is the cleaner.
It one instance of th process is started for each cleaner
both eu and iu dirty beds are put into the same queue fifo
cleaner puts the clean bed in the right clean bed queue
"""
while True:
# wait untile there is a bed in the dirty bead queue
bed = yield self.bed_dirty.get()
print(f'{self.env.now:.2f} cleaner {cleaner_id} has started to clean bed {bed.type} {bed.id}')
# clean bed
yield self.env.timeout(50)
print(f'{self.env.now:.2f} cleaner {cleaner_id} has finish cleaning bed {bed.type} {bed.id}')
# put bed in the right clean bed queue base on type, loop to wait for next dirty bead
if bed.type == 'EU':
yield self.eu_bed_clean.put(bed)
else:
yield self.iu_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
triage_service_time = random.expovariate(1.0/18)
yield self.env.timeout(triage_service_time)
print(f'{self.env.now:.2f} patient {pt.id} has been triaged')
# yield self.pt_ed_q.put(Patients.id)
# pt_id = yield self.pt_ed_q.get()
# Bed_Mgmt.check_q(pt_id, self.pt_ed_q, self.bed_clean, self.bed_dirty, self.bed_cleaner)
bed = yield self.eu_bed_clean.get()
pt.bed = bed
print(f'{self.env.now:.2f} patient {pt.id} has a clean bed {bed.type} {bed.id}')
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":
# get iu bed
bed = yield self.iu_bed_clean.get()
# move patient to new bed
yield self.bed_dirty.put(pt.bed)
print(f'{self.env.now:.2f} patient {pt.id} moved to IU giving up bed {pt.bed.type} {pt.bed.id} and taking bed {bed.type} {bed.id}')
pt.bed = bed
# time until IU bed becomes becone available
yield self.env.timeout(60)
yield self.bed_dirty.put(pt.bed)
print(f'{self.env.now:.2f} patient {pt.id} left IU giving up bed {pt.bed.type} {pt.bed.id}')
else:
# patient leaves hospital
yield self.bed_dirty.put(pt.bed)
print(f'{self.env.now:.2f} patient {pt.id} left EU giving up bed {pt.bed.type} {pt.bed.id}')
def run(self):
self.env.process(self.generate_pt_arrivals())
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()
我只想在必要时使用床清洁器。如下代码所示,没有出现错误,但结果不准确。增加或减少清洁器数量应该会改变结果,但无论清洁器数量如何变化,结果都是相同的。 也许我可以猜到,每当我使用 'env.process()' 时,“self.bed_cleaner”都会被重置。所以,清洁工总是闲着……但我不确定。 你觉得我不明白什么?请帮助我,我可以正确地进行实验。
import simpy
import random
class Pre_define:
ed_bed_cleaning_request = True
class Patients:
def __init__(self, p_id):
self.id = p_id
self.edbed_name = ""
self.iubed_name = ""
self.admission_decision = ""
self.wtime_bed_NotClean = float("nan")
def admin_decision(self):
if (self.id % 2) == 0: # even dis, else IU 50%
self.admission_decision = "DIS"
else:
self.admission_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.edbed_clean = simpy.Store(self.env, capacity = 4)
self.iubed_clean = simpy.Store(self.env, capacity = 4)
self.bed_dirty = simpy.Store(self.env, capacity = 8)
self.bed_cleaner = simpy.Resource(self.env, capacity = 1)
def generate_beds(self):
for i in range(4):
yield self.env.timeout(0)
yield self.edbed_clean.put(f'edbed{i}')
yield self.iubed_clean.put(f'iubed{i}')
def generate_pt_arrivals(self):
while True:
pt = Patients(self.pt_counter)
yield self.env.timeout(5)
self.env.process(self.process(pt))
self.pt_counter += 1
def clean_beds_process(self, pt):
bed = yield self.bed_dirty.get()
while True:
if (Pre_define.ed_bed_cleaning_request == True and bed[:2] == 'ed') or (Pre_define.ed_bed_cleaning_request == False and bed[:2] == 'iu'):
with self.bed_cleaner.request() as bedreq:
yield bedreq
yield self.env.timeout(30)
if bed[:2] == 'ed':
yield self.edbed_clean.put(bed)
else:
yield self.iubed_clean.put(bed)
break
elif (Pre_define.ed_bed_cleaning_request == False and bed[:2] == 'ed') or (Pre_define.ed_bed_cleaning_request == True and bed[:2] == 'iu'):
with self.bed_cleaner.request() as bedreq:
yield bedreq
yield self.env.timeout(30)
if bed[:2] == 'ed':
yield self.edbed_clean.put(bed)
else:
yield self.iubed_clean.put(bed)
else:
break
def process(self, pt):
with self.tg.request() as req:
yield req
yield self.env.timeout(10)
if self.edbed_clean.items == [] and self.bed_dirty.items != []:
Pre_define.ed_bed_cleaning_request = True
self.env.process(self.clean_beds_process(pt)) # =========> This part I use env.process() for call cleaner
elif self.edbed_clean.items == [] and self.bed_dirty.items == []:
self.env.process(self.clean_beds_process(pt))
Pre_define.ed_bed_cleaning_request = True
else:
Pre_define.ed_bed_cleaning_request = True
edbed = yield self.edbed_clean.get()
pt.edbed_name = edbed
pt.admin_decision()
if pt.admission_decision != "DIS":
if self.iubed_clean.items == [] and self.bed_dirty.items != []:
Pre_define.ed_bed_cleaning_request = False
self.env.process(self.clean_beds_process(pt)) # =========> This part I use env.process() for call cleaner
elif self.iubed_clean.items == [] and self.bed_dirty.items == []:
self.env.process(self.clean_beds_process(pt))
Pre_define.ed_bed_cleaning_request = False
else:
Pre_define.ed_bed_cleaning_request = False
iubed = yield self.iubed_clean.get()
pt.iubed_name = iubed
dirty_edbed_name = pt.edbed_name
yield self.bed_dirty.put(dirty_edbed_name)
yield self.env.timeout(60) # IU bed occupied time
dirty_iubed_name = pt.iubed_name
yield self.bed_dirty.put(dirty_iubed_name)
else:
dirty_bed_name = pt.edbed_name
yield self.bed_dirty.put(dirty_bed_name)
def run(self):
self.env.process(self.generate_beds())
self.env.process(self.generate_pt_arrivals())
self.env.run(until = 200)
run_model = Model(0)
run_model.run()
病人只有干净的床。 EU 和 IU 床都在清洁中。两种类型的脏床被放入一个共同的床清洁队列中。清洁工足够聪明,可以将 eu 床放入 eu clean bed 队列,将 iu 床放入 clean iu bed 队列。还减少了 iu 处理时间,使脏 iu 床更快地出现在日志中。 Bed 现在是具有 ID 和类型的 class。否则这是之前几个问题中的同一个程序
"""
Hospital bed sim 3
Patient arrives,
gets trianged,
gets a clean eu bed from clean eu bed queue
leaves eu bed which is queued for cleaning beds
if admitted get iu bed from clean iu bed queue
gets treated
leaves, puting the iu bed in the queue for cleaning.
bed cleaners wait for beds to show up in cleaning queue
both eu and iu beds are in the same queue
after cleaning a bed it is put into is clean bed queue
(clean eu beds go to the clean eu queue, clean iu beds go to the clean iu queue)
Programer Michael R. Gibbs
"""
import simpy
import random
class Pre_Define:
warmup_period = 1440
sim_duration = 14400
number_of_runs = 1 #3
eu_beds= 77
iu_beds=50
class Bed():
"""
Hosptial beds, can have two types emergency (eu) and inpatiient (iu)
"""
def __init__(self, id, type):
self.id = id
self.type = type
class Patients:
"""
enity model is processing
uses beds
"""
def __init__(self, p_id):
self.id = p_id
self.bed = None
self.admission_decision = ""
def admin_decision(self):
"""
decides if a eu patient becmes a iu patient
"""
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.iu_bed_clean = simpy.Store(self.env)
self.eu_bed_clean = simpy.Store(self.env)
self.bed_dirty = simpy.Store(self.env)
self.run_number = run_number
def generate_beds(self):
"""
create the clean eu and iu beds
"""
self.eu_bed_clean.items = [Bed(i+1, "EU") for i in range(Pre_Define.eu_beds)]
self.iu_bed_clean.items = [Bed(i+1, "IU") for i in range(Pre_Define.iu_beds)]
def generate_pt_arrivals(self):
while True:
self.pt_counter += 1
pt = Patients(self.pt_counter)
#yield self.env.timeout(1/7)
yield self.env.timeout(5)
self.env.process(self.ed_process(pt))
def clean_beds_process(self, cleaner_id):
"""
contious process for cleaning beds
feeds off of the dirty bed queue
if the queue is empty, will wait
until a bed is added to the queue.
Clean beds are returned to the clean bed queue
This process is the cleaner.
It one instance of th process is started for each cleaner
both eu and iu dirty beds are put into the same queue fifo
cleaner puts the clean bed in the right clean bed queue
"""
while True:
# wait untile there is a bed in the dirty bead queue
bed = yield self.bed_dirty.get()
print(f'{self.env.now:.2f} cleaner {cleaner_id} has started to clean bed {bed.type} {bed.id}')
# clean bed
yield self.env.timeout(50)
print(f'{self.env.now:.2f} cleaner {cleaner_id} has finish cleaning bed {bed.type} {bed.id}')
# put bed in the right clean bed queue base on type, loop to wait for next dirty bead
if bed.type == 'EU':
yield self.eu_bed_clean.put(bed)
else:
yield self.iu_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
triage_service_time = random.expovariate(1.0/18)
yield self.env.timeout(triage_service_time)
print(f'{self.env.now:.2f} patient {pt.id} has been triaged')
# yield self.pt_ed_q.put(Patients.id)
# pt_id = yield self.pt_ed_q.get()
# Bed_Mgmt.check_q(pt_id, self.pt_ed_q, self.bed_clean, self.bed_dirty, self.bed_cleaner)
bed = yield self.eu_bed_clean.get()
pt.bed = bed
print(f'{self.env.now:.2f} patient {pt.id} has a clean bed {bed.type} {bed.id}')
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":
# get iu bed
bed = yield self.iu_bed_clean.get()
# move patient to new bed
yield self.bed_dirty.put(pt.bed)
print(f'{self.env.now:.2f} patient {pt.id} moved to IU giving up bed {pt.bed.type} {pt.bed.id} and taking bed {bed.type} {bed.id}')
pt.bed = bed
# time until IU bed becomes becone available
yield self.env.timeout(60)
yield self.bed_dirty.put(pt.bed)
print(f'{self.env.now:.2f} patient {pt.id} left IU giving up bed {pt.bed.type} {pt.bed.id}')
else:
# patient leaves hospital
yield self.bed_dirty.put(pt.bed)
print(f'{self.env.now:.2f} patient {pt.id} left EU giving up bed {pt.bed.type} {pt.bed.id}')
def run(self):
self.env.process(self.generate_pt_arrivals())
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()