You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 23:02:11