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

Simpy离散事件模拟中维修人员资源请求异常占用问题求解

Simpy离散事件模拟维修环节死锁问题解决方案

问题根因

你当前逻辑的死锁来源于资源请求和条件判断的顺序错误:

  • 调用self.repairman.request()并执行yield request_repair之后,Simpy会直接将该维修人员标记为占用状态,self.repairman.count会加1
  • 你后续的while循环判断条件包含self.repairman.count==self.num_repairman,当所有维修人员都被你的请求占用后,该条件永远成立,程序陷入无限等待
  • 额外的逻辑问题:你将顾客置换流程和产品维修流程绑定在同一个进程中,不符合实际业务逻辑,维修应该是独立于顾客到店的后台持续流程。

修复方案

1. 架构调整

单独启动一个后台维修进程,循环检测坏产品库存,只要有坏产品且有空闲维修人员就触发维修,不需要和顾客流程绑定,也能正确记录维修人员队列数据。

2. 资源请求逻辑调整

如果需要保留当前绑定逻辑的写法,调整请求和判断的顺序:先发起资源请求(此时请求会进入队列,len(self.repairman.queue)会正确更新,满足你记录队列数据的需求),先判断所有前置条件满足后,再yield等待资源分配,拿到资源后直接执行维修。

3. 代码bug修复

  • 修正导入语句:import simpy而非import simply
  • 在__init__方法中初始化self.lost_customers = 0,避免属性不存在报错
  • 移除while循环中冗余的维修人员可用判断,资源请求本身就会等待空闲维修人员

可运行的修正后代码

import simpy
class Store(object):
    def __init__(self, env, num_cashiers, num_repairman):
        self.env = env
        self.num_cashiers = num_cashiers
        self.num_repairman = num_repairman
        self.cashiers = simpy.Resource(env, capacity=num_cashiers)
        self.repairman = simpy.Resource(env, capacity=num_repairman)
        
        self.total_customers = 0
        self.lost_customers = 0
        self.broken_product = 0
        self.repaired_product = 25
        
        self.resource_data = []
        # 启动后台维修进程
        env.process(self.repair_daemon())

    def customer_generator(self, env):
        customer_buffer = 5
        product_id = 1
        customer_interarrival_time = 100
        
        while True:
            if len(self.cashiers.queue) >= customer_buffer:
                self.lost_customers +=1
            else:
                env.process(self.store_operations(env, product_id))
            yield env.timeout(customer_interarrival_time)
            product_id+=1
            self.total_customers +=1

    def serve_customer(self, product_id):
        yield self.env.timeout(90)
        self.broken_product +=1
        self.repaired_product -=1
       
    def repair_product(self, product_id):
        yield self.env.timeout(300)
        self.broken_product -=1
        self.repaired_product +=1

    def repair_daemon(self):
        # 后台维修进程,独立处理所有坏产品
        product_id = 0
        while True:
            # 等待有坏产品
            while self.broken_product == 0:
                yield self.env.timeout(1)
            # 发起维修人员请求,此时队列数据会正确更新
            request_repair = self.repairman.request()
            yield request_repair
            # 拿到资源直接维修
            product_id +=1
            yield self.env.process(self.repair_product(product_id))
            self.repairman.release(request_repair)
            # 记录数据
            self.resource_data.append({
                'time' : self.env.now,
                'broken product inv' : self.broken_product,
                'repaired product inv': self.repaired_product,
                'busy cashiers' : self.cashiers.count,
                'cashier queue' : len(self.cashiers.queue),
                'busy repairmen' : self.repairman.count,
                'repairmen queue' : len(self.repairman.queue)
            })

    def store_operations(self, env, product_id):
        # 顾客置换流程
        request_cashier = self.cashiers.request()
        yield request_cashier
        # 等待有可用的修复产品
        while self.repaired_product == 0:
            yield env.timeout(1)
        # 执行顾客服务
        yield env.process(self.serve_customer(product_id))
        self.cashiers.release(request_cashier)
        return

if __name__ == "__main__":
    env = simpy.Environment()
    store1 = Store(env, 3, 3)
    env.process(store1.customer_generator(env))
    env.run(500)
    # 输出记录数据
    for i in range(min(7, len(store1.resource_data))):
        print(store1.resource_data[i])

内容的提问来源于stack exchange,提问作者Boblo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 05:24:04