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

SimPy订单履行模拟系统无报错但卡顿无结果求助

问题描述

我想用SimPy模拟一套订单履行系统,系统规则如下:

  • 存在n个订单,每个订单包含mi个商品(i=1,2,…,n),所有订单的商品在模拟开始时已全部就绪,无需等待。
  • 若干loading resources(分拣人员),逐个扫描并将商品送往包装环节;处理完成后,商品会被加入对应订单的cart(订单容器),cart数量与订单数一致且无容量限制。
  • 当某个订单的cart中商品数量达到阈值(比如订单总商品数的10%)时,packaging resources(包装人员)开始逐个处理该订单的商品,可同时处理多个订单但每次仅处理一件商品。

我编写了代码,但运行时出现问题:每次随机选中一件商品(比如订单2的商品2),重复输出10条相同的分拣日志后系统卡顿,无后续结果输出。

我的代码

商品列表生成

from itertools import repeat
import simpy
import random 
import itertools

num_order = 2
size_order = [10, 8]
items = []
for i in range(num_order):
    ob = list(zip(repeat(i+1), (range(1,size_order[i]+1))))
    items.append(ob)

items = list(itertools.chain(*items))

逻辑:生成包含(订单号,商品号)元组的商品列表,示例中2个订单分别含10、8件商品。

商品生成函数

def gen_items(env,mean_load,mean_pack,items,load_op,pack_op,cart,size_order):
    
# Choose a random item from the list of all items, 
#give it an id of it's tuple name, and remove that item from the list
    if items:
        item_id = random.choice(items)
        items.remove(item_id)
        
    while True:
        w = gen_activity(env,mean_load,mean_pack,item_id,load_op,pack_op,cart,size_order)
        
        env.process(w)
        
        yield env.timeout(0) #items are ready and don't take time to be available for the operator

逻辑:随机选取商品并启动处理流程,商品就绪无等待时间。

活动处理函数

def gen_activity(env,mean_load,mean_pack,item_id,load_op,pack_op,cart,size_order):
    
    
    time_enter_load_op_queue = env.now #time item is ready for loading
    
    
    with load_op.request() as req:
        
        yield req  # we request an operator
         
        time_queue_load_op = env.now
        time_in_load_op_queue = time_queue_load_op - time_enter_load_op_queue
        print("item" +str(item_id[1])+ " of order" + str(item_id[0])+" entered load at" + str(time_enter_load_op_queue)+ " and spent"+ str(time_in_load_op_queue))
      # print the time the item spent in the queue waiting for loading operator
        
        load_time = random.expovariate(1/mean_load)
        yield env.timeout(load_time)

       # once the item is processed, it then is loaded to the cart of that order in 45 time untis
        yield cart[item_id[0]-1].put(1)
        yield env.timeout(45)
        
    
        
    time_enter_pack_op_queue = env.now #now the item at the packaging location
        
    
    with pack_op.request() as req:
        
        if cart[item_id[0]-1].level >= 0.1*(size_order[item_id[0]-1]):

            yield req # request a packaging operator to start packaging only if there is 10% of the order in the cart

        time_queue_pack_op = env.now
        time_in_pack_op_queue = time_queue_pack_op - time_enter_pack_op_queue
        print("item" +str(item_id[1])+ " of order" + str(item_id[0])+" entered pack at" + str(time_enter_pack_op_queue)+ " and spent"+ str(time_in_pack_op_queue))

        pack_time = random.expovariate(1/mean_pack)
        yield env.timeout(pack_time)     # time to pack 

逻辑:实现分拣、入cart、包装流程,包装环节需满足cart商品量达阈值才请求包装资源。

初始化与运行

env = simpy.Environment()
load_op = simpy.Resource(env,capacity=10)
pack_op = simpy.Resource(env,capacity=2)

cart = []
for i in range(len(size_order)):
    
    c = simpy.Container(env,capacity=size_order[i],init=0)
    cart.append(c)
    

mean_load,mean_pack = 3,2

env.process(gen_items(env,mean_load,std_load,mean_pack,std_pack,items,load_op,pack_op,chute,size_order))

env.run(until=1000)

问题排查与修正

核心问题分析

  1. gen_items函数逻辑错误:仅在函数开头随机选一次商品并移除,后续while True循环一直复用同一个item_id,导致同一商品被反复处理;同时yield env.timeout(0)会让循环无限快速执行,瞬间创建大量重复进程引发卡顿。
  2. 初始化参数错误:调用gen_items时传入了未定义的std_load、std_pack、chute参数,与函数定义不匹配。
  3. 包装环节逻辑缺陷:未达阈值时直接跳过资源请求并执行包装计时,不符合“达到阈值才开始处理”的规则;且未等待cart满足条件就进入包装流程。

修正后的完整代码

from itertools import repeat
import simpy
import random 
import itertools

num_order = 2
size_order = [10, 8]
items = []
for i in range(num_order):
    ob = list(zip(repeat(i+1), range(1, size_order[i]+1)))
    items.append(ob)

items = list(itertools.chain(*items))

def gen_items(env, mean_load, mean_pack, items, load_op, pack_op, cart, size_order):
    # 遍历所有商品,逐个启动处理流程,直到商品耗尽
    while items:
        item_id = random.choice(items)
        items.remove(item_id)
        env.process(gen_activity(env, mean_load, mean_pack, item_id, load_op, pack_op, cart, size_order))
        yield env.timeout(0)  # 商品就绪无等待,快速启动下一个

def gen_activity(env, mean_load, mean_pack, item_id, load_op, pack_op, cart, size_order):
    order_idx = item_id[0] - 1
    order_size = size_order[order_idx]
    threshold = 0.1 * order_size

    # 分拣环节
    time_enter_load_op_queue = env.now
    with load_op.request() as req:
        yield req
        time_in_load_op_queue = env.now - time_enter_load_op_queue
        print(f"item {item_id[1]} of order {item_id[0]} entered load at {time_enter_load_op_queue:.2f}, spent {time_in_load_op_queue:.2f} in queue")
        
        load_time = random.expovariate(1/mean_load)
        yield env.timeout(load_time)
        
        # 商品加入cart,保留运输到包装区的45单位时间
        yield cart[order_idx].put(1)
        yield env.timeout(45)

    # 包装环节:等待cart达到阈值后再请求资源
    time_enter_pack_op_queue = env.now
    # 等待cart商品量满足阈值条件
    yield env.event() until (cart[order_idx].level >= threshold)
    
    with pack_op.request() as req:
        yield req
        time_in_pack_op_queue = env.now - time_enter_pack_op_queue
        print(f"item {item_id[1]} of order {item_id[0]} entered pack at {time_enter_pack_op_queue:.2f}, spent {time_in_pack_op_queue:.2f} in queue")
        
        pack_time = random.expovariate(1/mean_pack)
        yield env.timeout(pack_time)

# 初始化模拟
env = simpy.Environment()
load_op = simpy.Resource(env, capacity=10)
pack_op = simpy.Resource(env, capacity=2)

cart = []
for i in range(len(size_order)):
    # 设置cart为无容量限制
    c = simpy.Container(env, capacity=float('inf'), init=0)
    cart.append(c)

mean_load, mean_pack = 3, 2

# 修正参数调用
env.process(gen_items(env, mean_load, mean_pack, items, load_op, pack_op, cart, size_order))

env.run(until=1000)

关键修正点说明

  1. gen_items函数:将商品选择逻辑移入while items循环,确保每次处理新商品,商品耗尽后自动停止循环。
  2. 参数修正:删除未定义的参数,替换为正确的cart等参数;将cart的capacity设为float('inf')以实现无容量限制。
  3. 包装环节优化:添加等待cart达到阈值的逻辑,只有满足条件后才请求包装资源,符合系统规则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 08:25:20