Simpy仿真代码修改:基于护士资源与队列的诊疗逻辑优化
SimPy患者诊疗流程定制解决方案
核心思路
普通simpy.Resource无法直接满足你的业务规则,因为它的队列和资源状态封装较深,难以灵活判断并触发双人协作逻辑。我们可以通过独立护士资源+等待队列+自定义调度器的组合实现需求:
- 用两个容量为1的
simpy.Resource分别代表两名护士 - 用
simpy.Store维护患者等待队列 - 编写专门的调度进程,实时监控护士空闲状态和队列长度,按规则分配服务模式
完整实现代码
import simpy import numpy as np np.random.seed(1) # 生成到达时间(指数分布) def draw_arrival_time(): return np.random.exponential(2.0) # 生成基础诊疗时间(正态分布,避免负时间) def draw_service_time(): return max(np.random.normal(5.0, 1.0), 0.1) # 患者到达生成器 def patient_generator(env, patient_queue): patient_id = 1 while True: # 患者到达,加入等待队列 print(f"患者 {patient_id} 到达,时间: {env.now:.2f}") yield patient_queue.put({"id": patient_id, "arrival_time": env.now}) # 下一位患者到达间隔 next_arrival = draw_arrival_time() yield env.timeout(next_arrival) patient_id += 1 # 单个护士服务逻辑 def single_nurse_service(env, nurse, patient, waiting_times): with nurse.request() as req: yield req start_time = env.now waiting_time = start_time - patient["arrival_time"] waiting_times.append(waiting_time) print(f"患者 {patient['id']} 开始单人诊疗,时间: {start_time:.2f},等待时长: {waiting_time:.2f}") # 基础诊疗时间 service_time = draw_service_time() yield env.timeout(service_time) print(f"患者 {patient['id']} 完成单人诊疗,时间: {env.now:.2f}") # 双人协作服务逻辑 def double_nurse_service(env, nurse1, nurse2, patient, waiting_times): # 同时请求两名护士,确保两人都空闲才启动服务 with nurse1.request() as req1, nurse2.request() as req2: yield req1 & req2 start_time = env.now waiting_time = start_time - patient["arrival_time"] waiting_times.append(waiting_time) print(f"患者 {patient['id']} 开始双人协作诊疗,时间: {start_time:.2f},等待时长: {waiting_time:.2f}") # 诊疗时间减半 service_time = draw_service_time() / 2 yield env.timeout(service_time) print(f"患者 {patient['id']} 完成双人协作诊疗,时间: {env.now:.2f}") # 核心调度器:按业务规则分配服务模式 def nurse_scheduler(env, nurse1, nurse2, patient_queue, waiting_times): while True: # 无患者时短轮询等待 if len(patient_queue.items) == 0: yield env.timeout(0.1) continue # 获取当前护士状态和队列长度 nurse1_idle = (nurse1.count == 0) nurse2_idle = (nurse2.count == 0) queue_length = len(patient_queue.items) if nurse1_idle and nurse2_idle: if queue_length == 1: # 双人协作服务单个患者 patient = yield patient_queue.get() env.process(double_nurse_service(env, nurse1, nurse2, patient, waiting_times)) elif queue_length >= 2: # 取出两名患者,各分配一名护士 patient1 = yield patient_queue.get() patient2 = yield patient_queue.get() env.process(single_nurse_service(env, nurse1, patient1, waiting_times)) env.process(single_nurse_service(env, nurse2, patient2, waiting_times)) else: # 有空闲护士时处理队列中的单个患者 if (nurse1_idle or nurse2_idle) and queue_length >= 1: patient = yield patient_queue.get() if nurse1_idle: env.process(single_nurse_service(env, nurse1, patient, waiting_times)) else: env.process(single_nurse_service(env, nurse2, patient, waiting_times)) else: # 无空闲护士,短轮询等待状态变化 yield env.timeout(0.1) # 主仿真流程 if __name__ == "__main__": env = simpy.Environment() # 初始化两名独立护士资源 nurse1 = simpy.Resource(env, capacity=1) nurse2 = simpy.Resource(env, capacity=1) # 患者等待队列 patient_queue = simpy.Store(env) waiting_times = [] # 启动患者生成器和调度器 env.process(patient_generator(env, patient_queue)) env.process(nurse_scheduler(env, nurse1, nurse2, patient_queue, waiting_times)) # 运行仿真90单位时间 env.run(until=90) # 输出统计结果 if waiting_times: average_wait = np.mean(waiting_times) print(f"\n平均等待时长: {average_wait:.2f}") else: print("无患者完成诊疗")
代码关键点说明
- 队列与调度分离:患者到达后先进入
Store队列,由调度器统一处理,避免了Resource自带队列的黑盒问题 - 状态透明化:通过
nurse.count直接获取护士忙碌状态,结合队列长度精准触发对应服务逻辑 - 双人协作实现:用
req1 & req2同时请求两名护士,确保只有两人都空闲时才启动协作服务,诊疗时间自动减半 - 轮询机制:调度器通过短时间超时轮询,实时监控队列和护士状态,保证规则及时触发
内容的提问来源于stack exchange,提问作者user_42
相关产品推荐
相关产品推荐

