SimPy中3个具有不同特性的资源

3 投票
1 回答
1935 浏览
提问于 2025-04-18 14:06

我正在尝试模拟一个场景,里面有5台机器,它们的工作顺序是1 -> 3 -> 1。也就是说,中间的3台机器是同时工作的,这样可以减少它们的有效工作时间。

我可以很简单地通过创建一个SimPy资源,设置值为3来模拟这个场景,像这样:

simpy.Resource(env, capacity=3)

不过在我的情况下,这三台机器的工作方式稍有不同,有时候我想随便用其中一台(在工作时),或者预定一台特定的机器(在清洁时)。基本上,这三台机器的脏污程度上升的速度不同,工作速度也会变慢,我想模拟这些情况,并且在某台机器太脏时能够安排清洁。

我尝试了几种方法来模拟这个情况,但每次都遇到问题。

第一次尝试时,当预定资源时,它还预定了3台机器中的一台(A、B、C),并设置了一个标志来告诉我正在使用哪台机器。这种方法虽然可行,但不够简洁,导致代码中到处都是复杂的if语句,让人很难理解发生了什么。

第二次我尝试把它建模为三种独立的资源,然后试图等待并请求其中一台机器,像这样:

reqA = A.res.request()
reqB = B.res.request()
reqC = C.res.request()

unitnumber = yield reqA | reqB | reqC
yield env.process(batch_op(env, name, machineA, machineB, machineC, unitnumber))

但这样不行,我也搞不清楚如何选择其中一台机器。

那么,模拟这个场景的最佳方法是什么呢?为了完整性,我想要实现以下几点:

  1. 请求任意一台3台机器
  2. 请求特定的一台机器
  3. 让每台机器记录它的历史
  4. 让每台机器的特性不同,比如有的机器脏得快但最开始工作得快
  5. 根据性能或指标检测并安排清洁

这是我在最新版本中尝试将每台机器建模为独立资源的进展:

class Machine(object):

    def __init__(self, env, cycletime, cleantime, k1foul, k2foul):
        self.env = env
        self.res = simpy.Resource(env, 1)

        self.cycletime = cycletime
        self.cleantime = cleantime
        self.k1foul = k1foul
        self.k2foul = k2foul
        self.batchessinceclean = 0

    def operate(self):
        self.cycletime = self.cycletime + self.k2foul * np.log(self.k1foul * self.batchessinceclean + 1)
        self.batchessinceclean += 1
        yield self.env.timeout(self.cycletime) 

    def clean(self):
        print('%s begin cleaning at %s' % (self.env.now))
        self.batchessinceclean = 0
        yield env.timeout(self.cleantime)
        print('%s finished cleaning at %s' % (self.env.now))

1 个回答

6

你可以试试 (Filter)Store:

import simpy


def user(machine):
    m = yield machine.get()
    print(m)
    yield machine.put(m)

    m = yield machine.get(lambda m: m['id'] == 1)
    print(m)
    yield machine.put(m)

    m = yield machine.get(lambda m: m['health'] > 98)
    print(m)
    yield machine.put(m)


env = simpy.Environment()
machine = simpy.FilterStore(env, 3)
machine.put({'id': 0, 'health': 100})
machine.put({'id': 1, 'health': 95})
machine.put({'id': 2, 'health': 97.2})

env.process(user(machine))

env.run()

撰写回答