You need to enable JavaScript to run this app. Python SimPy单次取料后按时间间隔多次生成库存的实现问题
优惠活动
大模型
产品
解决方案
定价
更多

Python SimPy单次取料后按时间间隔多次生成库存的实现问题

现有代码的问题根源

两处逻辑错误直接导致延迟失效、流程和预期不符:

  • 自定义的delay()函数完全无法生效:SimPy的协程模型需要靠流程中的yield语句把阻塞动作暴露给仿真环境,你直接调用delay(2)只会生成一个从未被执行的生成器对象——哪怕函数内部的逻辑正确,因为没有外层流程yield这个生成器,仿真环境根本感知不到这个延迟动作,自然不会产生时间阻塞。
  • 流程嵌套层级错误:你期望的流程是「单次取1单位原材料→完成所有拆分批次的间隔产出→再取下一份原材料」,但原代码跑完无效的delay调用后,直接走外层的yield env.timeout(1)就跳转回下一轮循环取料,既没有按要求等待批次间隔,也没有把多批次产出的逻辑完整执行完。
修正方案

要实现目标逻辑,只需要调整流程的嵌套结构,不需要额外封装延迟函数:

  1. 最外层保留无限循环,循环内第一步完成1单位原材料的获取
  2. 取料成功后,进入内层的批次产出循环:每一轮循环先入库指定数量的产品,再通过yield env.timeout(批次间隔)实现等待,等所有批次全部完成、最后一次等待结束后,再回到最外层循环取下一份原材料
  3. 全程把取料动作放在批次循环的外侧,从结构上避免重复取料的可能。
可直接运行的修正代码
import simpy

class Factory():
    def __init__(self, env):
        self.materials = simpy.Container(env, capacity = 10000, init = 9000)
        self.stock = simpy.FilterStore(env, capacity = 10000) 
        
def create_stock(env, factory):
    # 按你的需求配置参数:分3批、每批5件、批次间隔6个仿真时间
    batch_total = 3    # 单份原材料拆分的产出批次数量
    batch_size = 5     # 每批次产出的成品数量
    batch_interval = 6 # 相邻批次的仿真时间间隔
    global_item_id = 0 # 给每个生成的成品分配唯一id
    
    while True:
        print(f'当前时间:{env.now:.1f} 剩余原材料:{factory.materials.level} 成品库存:{len(factory.stock.items)}')
        # 仅在外层循环入口取1单位原材料,取料动作全程只在这一处触发
        yield factory.materials.get(1)
        
        # 取料完成后执行所有批次产出,全程不会跳回取料步骤
        for _ in range(batch_total):
            # 批量入库当前批次的成品
            for _ in range(batch_size):
                factory.stock.put({'order_id': 'order_id', 'id': global_item_id})
                global_item_id += 1
            # 本批次完成后,等待固定间隔再启动下一批
            yield env.timeout(batch_interval)
        
        # 所有批次产出全部完成后,自动进入下一轮取料流程
        

env = simpy.Environment()
factory = Factory(env)
on_process = env.process(create_stock(env, factory))


print('start...')
env.run(until = 30)
print('end')
实操注意点
  • 只要把yield factory.materials.get(1)的动作放在所有批次循环的外层,从结构上就不会出现“跑到一半重复取料”的问题:SimPy协程是按顺序执行的,只有遇到带yield的阻塞语句才会暂停切换流程,整个内层批次循环没有嵌入取料动作,就不会重复扣减原材料。
  • 不要在SimPy流程里直接调用生成器类型的函数但不做yield处理,所有需要阻塞流程的动作(资源获取、时间等待)必须通过当前流程的yield语句传递给仿真环境,否则环境完全无法识别这些动作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.31 07:54:01