At the moment I am creating doctors as following:
doctor = simpy.Resource(self.env, capacity=3)
These doctors are requested for a flow of patients using the following:
with self.doctor.request() as req: yield req2 *patient encounter*
What I would like to do, is initialize the doctors with some kind of fatigue level (and other characteristics) like:
# Class representing a doctor and their characteristics class Doctor(object): def __init__(self, env, id, exp_level, fatigue): self.env = env self.id = id self.exp_level = exp_level self.fatigue = fatigue self.isAvailable = True
Then in the encounter I would like to access the doctor to add fatigue such as:
with self.doctor.request() as req: yield req2 *patient encounter* self.doctor.fatigue += 5
Where once the fatigue crosses a threshold the doctor goes on break and the fatigue is reset, such as:
def monitor_break(self): while True: if Doctor.fatigue > 9: Doctor.fatigue = 0 yield self.env.timeout(15)
Any idea on how to do this?
Advertisement
Answer
First I would use a store for your docs instead of using a resource. Second I would decorate the store with a get override to check if the doc needs a nap
something like this
""" A simple sim where Doctors put themselves on break when they get tired Programmer Michael R. Gibbs """ import simpy import random class Doctor(): """ Doctor that get tired """ def __init__(self, env, id): self.env = env self.id = id self.fatigue = 0 class Doc_Pool(): """ decorates a simpy store to chekc a doc's fatigue level and doing a timeout if fatigue is too high before returning the doc to the pool """ def __init__(self, env, num_of_docs, max_fatigue): self.env = env self.store = simpy.Store(env) self.store.items = [Doctor(env, i+1) for i in range(num_of_docs)] self.max_fatigue = max_fatigue def get(self): """ get a doc from the real store """ return self.store.get() def put(self, doc): """ put a doc in the store unless the doc needs a break """ if doc.fatigue > self.max_fatigue: # needs a break self.env.process(self._doc_timeout(doc)) else: self.store.put(doc) def _doc_timeout(self, doc): """ gives the doc a break, then put in store """ print(f'{self.env.now:.0f} doctor {doc.id} starting break with fatigue {doc.fatigue:0.2f}') yield self.env.timeout(doc.fatigue) doc.fatigue = 0 self.store.put(doc) print(f'{self.env.now:.0f} doctor {doc.id} ending break') class Patient(): """ Simple class to track patients """ next_id = 1 def __init__(self): self.id = self.get_next_id() @classmethod def get_next_id (cls): id =cls.next_id cls.next_id += 1 return id def gen_pats(env, doc_store): """ Generates the arrival off patients and queue them up for a doctor visit """ while True: pat = Patient() print(f'{env.now:.0f} patient {pat.id} has arrived') yield env.timeout(random.uniform(1,5)) env.process(doc_visit(env, pat, doc_store)) def doc_visit(env, pat, doc_store): """ gets a doc, do visit, add fatigue to doc, end visit """ doc = yield doc_store.get() print(f'{env.now:.0f} patient {pat.id} is visiting doctor {doc.id}') env.timeout(random.uniform(1,6)) doc.fatigue += random.uniform(1,5) doc_store.put(doc) print(f'{env.now:.0f} patient {pat.id} visiting doctor {doc.id} has ended') # boot up sim env = simpy.Environment() doc_store = Doc_Pool(env, 3, 10) env.process(gen_pats(env, doc_store)) env.run(200) print('end of simulation')