【问题标题】:Discrete Event Modelling - Simpy - how to model complex dependencies?离散事件建模 - Simpy - 如何建模复杂的依赖关系?
【发布时间】:2020-02-22 16:03:37
【问题描述】:

我是 Simpy 的新手,在弄清楚如何为具有复杂依赖关系的进程调度程序建模时遇到了麻烦。

我的问题的高级摘要

  • 我有一个仓库,通过入口接收装有物品的盒子。这些盒子被放入队列中等待处理。
  • 每个箱子都有一个目的地房间,并且必须使用传送带运送到那里。一条传送带为多个房间提供服务。
  • 只有当传送带和目标房间都可用时,操作员才会查看队列中的箱子并将箱子放在适当的传送带上。操作员按顺序发送盒子,但跳过无法处理的盒子。
  • 在房间内打开盒子后,需要一定的时间来存放物品。在此期间,房间无法接收其他盒子。
  • 物品入库后,空箱用进来的同一条传送带送到仓库出口。
  • 操作员始终了解哪些传送带和房间是空闲的。

我的问题是如何建模这个运算符。到目前为止,我还没有在 Simpy 中找到一种优雅的方式来做到这一点。我本质上想要一个只有在以下三个条件成立时才唤醒的过程:a)一个房间是空闲的; b) 这个房间的队列中有一个盒子,并且 c) 去房间的皮带是免费的。

非常感谢任何想法、建议或指向现有示例的指针。谢谢!

【问题讨论】:

    标签: python design-patterns simulation simpy event-simulation


    【解决方案1】:

    你可能想看看

    https://simpy.readthedocs.io/en/latest/topical_guides/resources.html#res-type-store

     from collections import namedtuple
    
     Machine = namedtuple('Machine', 'size, duration')
     m1 = Machine(1, 2)  # Small and slow
     m2 = Machine(2, 1)  # Big and fast
    
     env = simpy.Environment()
     machine_shop = simpy.FilterStore(env, capacity=2)
     machine_shop.items = [m1, m2]  # Pre-populate the machine shop
    
     def user(name, env, ms, size):
         machine = yield ms.get(lambda machine: machine.size == size)
         print(name, 'got', machine, 'at', env.now)
         yield env.timeout(machine.duration)
         yield ms.put(machine)
         print(name, 'released', machine, 'at', env.now)
    
    
     users = [env.process(user(i, env, machine_shop, (i % 2) + 1))
              for i in range(3)]
     env.run()
    

    关于盒子和房间,我建议你使用 2 种不同的资源 - 存储(资源类)来建模。

    a) 一个房间是免费的; (检查房间的资源存储是否为空)
    b) 队列中有一个box为这个房间寻址,(在namedtuple中定义box和room),可以使用get_queue查看

    c) 去房间的腰带是免费的。(类似于a点)

    【讨论】:

    • 感谢您的回复。不幸的是,它没有解决我的问题。可能我不够清楚。我知道如何使用 FilterStore,但我不知道如何在所有 3 个事件同时为真时唤醒。在我看来,在 Simpy 中,事件可以在复合条件的一部分时在不同时间触发。例如,我目前在腰带上循环并在条件事件yield (haveBoxEvent & haveRoomEvent & haveBeltEvent) | someTimeOut 上屈服。这无法正常工作,因为超时与介于 ( ... ) 之间的其他 AND 事件不互斥。
    • 例如,如果超时触发了一些(但不是全部)其他事件也可以被触发。例如,可以先获取腰带,然后获取盒子,但是在房间空闲之前超时到期。这意味着当我醒来时,我无法做任何有用的工作,但我阻塞了一些资源(例如,从队列中提取了一个盒子),这会打乱模拟。
    【解决方案2】:

    这是关于 simpy 的另一个 StackOverflow 问题,可能会让您更接近解决方案:How can I have a process wait for multiple resources?

    如果我正确理解了该答案,您可以将事件视为队列中的消息:查看它们,但将您不喜欢的那些放回原处。这意味着您可以等待整个事件列表,包括 .get() 和您的超时,当其中任何一个触发时,检查这些事件。您可以对其中一些采取行动并丢弃其余部分(让它们“未处理”以用于另一个过程或迭代)。这样,如果您的超时甚至在列表中,您就可以检查其他三个事件的状态并采取相应措施。

    【讨论】:

      猜你喜欢
      • 2017-12-30
      • 2023-02-26
      • 2022-01-06
      • 2013-02-03
      • 1970-01-01
      • 1970-01-01
      • 2015-12-28
      • 1970-01-01
      相关资源
      最近更新 更多