如何确定同时发生的 SimPy 事件的优先级?
How can I prioritize SimPy events that occur at the same time?
我 运行 在我的 SimPy 模拟中遇到了一个问题,其中多个事件以错误的顺序同时发生。具体来说,我正在为一条生产线建模,其中机器会定期发生故障并接受维护。当一台机器在t1
时间修好后,应该会在那个时候恢复生产。然而,事件发生的顺序是
- 检查修复是否完成
- 完成修复
- 如修复,恢复生产
当我想要的时候
- 完成修复
- 检查修复是否完成
- 如修复,恢复生产
有什么方法可以改变事件执行的顺序吗?
这是我遇到的问题的最简单示例:
import random
import simpy
class machine:
def __init__(self, env, process_time):
self.env = env
self.process_time = process_time
self.remaining_process_time = process_time
self.failed = False
self.parts_made = 0
env.process(self.production())
env.process(self.maintenance())
def production(self):
while True:
while self.remaining_process_time:
if random.random() < 0.1:
# machine fails
print(f'Machine failed at t={self.env.now}')
self.failed = True
while self.failed:
# wait for maintenance to finish
yield self.env.timeout(1)
print(f'Resuming production at t={self.env.now}\n')
yield self.env.timeout(1)
self.remaining_process_time -= 1
self.parts_made += 1
self.remaining_process_time = self.process_time
def maintenance(self):
while True:
while not self.failed:
# wait for failure to occur
yield self.env.timeout(1)
print(f'Starting repair at t={self.env.now}')
ttr = random.randint(1,8)
print(f'TTR={ttr}')
yield self.env.timeout(ttr)
self.failed = False
self.remaining_process_time = self.process_time
print(f'Finished repair at t={self.env.now}')
random.seed(1234)
env = simpy.Environment()
system = machine(env, 5)
env.run(until=50)
输出为:
Machine failed at t=2
Starting repair at t=2
TTR=1
Finished repair at t=3
Resuming production at t=4
Machine failed at t=6
Starting repair at t=6
TTR=6
Finished repair at t=12
Resuming production at t=12
Machine failed at t=14
Starting repair at t=15
TTR=1
Finished repair at t=16
Resuming production at t=16
Machine failed at t=23
Starting repair at t=24
TTR=8
Finished repair at t=32
Resuming production at t=32
Machine failed at t=37
Starting repair at t=38
TTR=2
Finished repair at t=40
Resuming production at t=40
Machine failed at t=42
Starting repair at t=43
TTR=2
Finished repair at t=45
Resuming production at t=45
对于第一次故障,修复在 t=3
正确完成,但生产直到 t=4
才恢复。再看第三次故障,故障发生在t=14
,但直到t=15
才开始修复。似乎这些进程 运行 并行(production
和 maintenance
)会产生问题并不一致地检查条件,所以我的想法是我需要完全重新设计它们。
我建议更改您的代码以避免出现您描述的情况。您描述的代码设计对事件过程敏感time/order,即使您正确设置了事件顺序,其他人也可能在以后的修订中出错。
如果你改变代码设计,让生产机器等待修复而不是定期检查,那么你应该避免这个问题。
接下来的流程是:
- 生产机器坏了;等待修复。
- 修理工完成维修;通知生产机器。
- 生产机器恢复生产。
问题似乎出现在多个进程同时调用 self.env.timeout(1)
时。这是我找到的解决方案:
class machine:
def __init__(self, env, process_time):
self.env = env
self.process_time = process_time
self.remaining_process_time = process_time
self.failed = False
self.parts_made = 0
env.process(self.production())
def production(self):
while True:
while self.remaining_process_time:
if random.random() < 0.1:
# machine fails
print(f'Machine failed at t={self.env.now}')
self.failed = True
yield self.env.process(self.maintenance())
print(f'Resuming production at t={self.env.now}\n')
yield self.env.timeout(1)
self.remaining_process_time -= 1
self.parts_made += 1
self.remaining_process_time = self.process_time
def maintenance(self):
print(f'Starting repair at t={self.env.now}')
ttr = random.randint(1,8)
print(f'TTR={ttr}')
yield self.env.timeout(ttr)
self.remaining_process_time = self.process_time
print(f'Finished repair at t={self.env.now}')
random.seed(1234)
env = simpy.Environment()
system = machine(env, 5)
env.run(until=50)
这段代码产生了我期望的输出。
Machine failed at t=2
Starting repair at t=2
TTR=1
Finished repair at t=3
Resuming production at t=3
Machine failed at t=5
Starting repair at t=5
TTR=6
Finished repair at t=11
Resuming production at t=11
Machine failed at t=13
Starting repair at t=13
TTR=1
Finished repair at t=14
Resuming production at t=14
...
我 运行 在我的 SimPy 模拟中遇到了一个问题,其中多个事件以错误的顺序同时发生。具体来说,我正在为一条生产线建模,其中机器会定期发生故障并接受维护。当一台机器在t1
时间修好后,应该会在那个时候恢复生产。然而,事件发生的顺序是
- 检查修复是否完成
- 完成修复
- 如修复,恢复生产
当我想要的时候
- 完成修复
- 检查修复是否完成
- 如修复,恢复生产
有什么方法可以改变事件执行的顺序吗?
这是我遇到的问题的最简单示例:
import random
import simpy
class machine:
def __init__(self, env, process_time):
self.env = env
self.process_time = process_time
self.remaining_process_time = process_time
self.failed = False
self.parts_made = 0
env.process(self.production())
env.process(self.maintenance())
def production(self):
while True:
while self.remaining_process_time:
if random.random() < 0.1:
# machine fails
print(f'Machine failed at t={self.env.now}')
self.failed = True
while self.failed:
# wait for maintenance to finish
yield self.env.timeout(1)
print(f'Resuming production at t={self.env.now}\n')
yield self.env.timeout(1)
self.remaining_process_time -= 1
self.parts_made += 1
self.remaining_process_time = self.process_time
def maintenance(self):
while True:
while not self.failed:
# wait for failure to occur
yield self.env.timeout(1)
print(f'Starting repair at t={self.env.now}')
ttr = random.randint(1,8)
print(f'TTR={ttr}')
yield self.env.timeout(ttr)
self.failed = False
self.remaining_process_time = self.process_time
print(f'Finished repair at t={self.env.now}')
random.seed(1234)
env = simpy.Environment()
system = machine(env, 5)
env.run(until=50)
输出为:
Machine failed at t=2
Starting repair at t=2
TTR=1
Finished repair at t=3
Resuming production at t=4
Machine failed at t=6
Starting repair at t=6
TTR=6
Finished repair at t=12
Resuming production at t=12
Machine failed at t=14
Starting repair at t=15
TTR=1
Finished repair at t=16
Resuming production at t=16
Machine failed at t=23
Starting repair at t=24
TTR=8
Finished repair at t=32
Resuming production at t=32
Machine failed at t=37
Starting repair at t=38
TTR=2
Finished repair at t=40
Resuming production at t=40
Machine failed at t=42
Starting repair at t=43
TTR=2
Finished repair at t=45
Resuming production at t=45
对于第一次故障,修复在 t=3
正确完成,但生产直到 t=4
才恢复。再看第三次故障,故障发生在t=14
,但直到t=15
才开始修复。似乎这些进程 运行 并行(production
和 maintenance
)会产生问题并不一致地检查条件,所以我的想法是我需要完全重新设计它们。
我建议更改您的代码以避免出现您描述的情况。您描述的代码设计对事件过程敏感time/order,即使您正确设置了事件顺序,其他人也可能在以后的修订中出错。
如果你改变代码设计,让生产机器等待修复而不是定期检查,那么你应该避免这个问题。
接下来的流程是:
- 生产机器坏了;等待修复。
- 修理工完成维修;通知生产机器。
- 生产机器恢复生产。
问题似乎出现在多个进程同时调用 self.env.timeout(1)
时。这是我找到的解决方案:
class machine:
def __init__(self, env, process_time):
self.env = env
self.process_time = process_time
self.remaining_process_time = process_time
self.failed = False
self.parts_made = 0
env.process(self.production())
def production(self):
while True:
while self.remaining_process_time:
if random.random() < 0.1:
# machine fails
print(f'Machine failed at t={self.env.now}')
self.failed = True
yield self.env.process(self.maintenance())
print(f'Resuming production at t={self.env.now}\n')
yield self.env.timeout(1)
self.remaining_process_time -= 1
self.parts_made += 1
self.remaining_process_time = self.process_time
def maintenance(self):
print(f'Starting repair at t={self.env.now}')
ttr = random.randint(1,8)
print(f'TTR={ttr}')
yield self.env.timeout(ttr)
self.remaining_process_time = self.process_time
print(f'Finished repair at t={self.env.now}')
random.seed(1234)
env = simpy.Environment()
system = machine(env, 5)
env.run(until=50)
这段代码产生了我期望的输出。
Machine failed at t=2
Starting repair at t=2
TTR=1
Finished repair at t=3
Resuming production at t=3
Machine failed at t=5
Starting repair at t=5
TTR=6
Finished repair at t=11
Resuming production at t=11
Machine failed at t=13
Starting repair at t=13
TTR=1
Finished repair at t=14
Resuming production at t=14
...