我使用的是 Simpy 4,但不知道如何同时安排多个事件。
例如,假设一条起跑线上有 3 辆车,我希望它们都同时出发。举个例子,下面的代码不能像我想要的那样工作,因为每次“移动”一个接一个地发生,而不是同时发生。
import simpy
from itertools import cycle
class Dispatch():
def __init__(self, env, cars):
self.cars = cars
self.action = env.process(self.run())
def run(self):
while True:
for car in self.cars:
yield env.process(car.move())
class Car():
def __init__(self, env, name, initial_location):
self.env = env
self.name = name
self.location = initial_location
self.path = iter(cycle(["A", "B", "C", "B"]))
def move(self):
yield env.timeout(1)
self.location = next(self.path)
print("{} is now at position {}, at time: {}".format(self.name, self.location, env.now))
env = simpy.Environment()
carA = Car(env, "carA", "A")
carB = Car(env, "carB", "A")
carC = Car(env, "carC", "A")
dispatcher = Dispatch(env, [carA,carB,carC])
env.run(until=20)
现在因为每辆车都是按顺序启动的,这给出了结果:
carA is now at position A, at time: 1
carB is now at position A, at time: 2
carC is now at position A, at time: 3
carA is now at position B, at time: 4
carB is now at position B, at time: 5
carC is now at position B, at time: 6
carA is now at position C, at time: 7
carB is now at position C, at time: 8
carC is now at position C, at time: 9
但我想要的是:
carA is now at position A, at time: 1
carB is now at position A, at time: 1
carC is now at position A, at time: 1
carA is now at position B, at time: 2
carB is now at position B, at time: 2
carC is now at position B, at time: 2
carA is now at position C, at time: 3
carB is now at position C, at time: 3
carC is now at position C, at time: 3
所以我想我正在寻找一种方法来重写 for 循环。
最后会有多辆车(就像上面的例子),我想分别控制每辆车。但我想作为一个起点,最好知道如何将每个汽车事件添加到事件列表中,以便它们同时开始。
有什么帮助吗?谢谢:)
最好的问候
编辑
好的,我不会把它作为答案,因为我不完全理解它。但我有我想要的结果。我创建了多个 Dispatch 对象,并分别运行每个对象。除非其他人可以清楚地解释这一点,否则我会等到我想通了再发布答案。
class Dispatch():
def __init__(self, env, car):
self.car = car
self.action = env.process(self.run())
def run(self):
while True:
yield env.process(self.car.moveto())
class Car():
def __init__(self, env, name, initial_location):
self.env = env
self.name = name
self.location = initial_location
self.path = cycle(["A", "B", "C", "B"])
def moveto(self):
if self.name == "carA":
yield env.timeout(1)
elif self.name == "carB":
yield env.timeout(4)
self.location = next(self.path)
print("{} is now at node: {}, at time: {}".format(self.name, self.location, env.now))
env = simpy.Environment()
carA = Car(env, "carA", "A")
carB = Car(env, "carB", "A")
cars = [carA, carB]
for car in cars:
Dispatch(env, car)
env.run(until=20)
答案 0 :(得分:0)
您可以同时使用 threading
运行汽车:
import time
import threading
from itertools import cycle
CARS = ['carA', 'carB', 'carC']
POS = ['A', 'B', 'C', 'D']
class Car:
def __init__(self, name):
self.name = name
self.pos = iter(cycle(POS))
self.time = 1
def run(self):
while self.time < 5:
pos = next(self.pos)
print(f'{self.name} is now at position {pos}, at time: {self.time}')
self.time += 1
time.sleep(1)
[threading.Thread(target=Car(car).run).start() for car in CARS]
输出:
carA is now at position A, at time: 1
carB is now at position A, at time: 1
carC is now at position A, at time: 1
carB is now at position B, at time: 2
carC is now at position B, at time: 2
carA is now at position B, at time: 2
carB is now at position C, at time: 3
carA is now at position C, at time: 3
carC is now at position C, at time: 3
答案 1 :(得分:0)
你的第一个密码就快到了
真正的问题是 Dispatcher 的 run 方法中的这一行。
yield env.process(car.move())
你需要降低收益
yield 使您的代码等待 car.move() 完成,然后再循环并启动下一辆车。
将您的代码更改为
env.process(car.move())
这将异步运行 car_move() 进程
我做的另一件事是将运动移到汽车上。让每辆车都有自己的超时时间为您提供了选择,例如因机械故障而中断一辆车。也可以给汽车类添加一个参数,给每辆车不同的速度
看下面的代码
import simpy
from itertools import cycle
class Dispatch():
def __init__(self, env, cars, startTime=0):
self.env = env
self.cars = cars
self.action = env.process(self.run(startTime))
def run(self,startTime):
# wait for start of race
yield self.env.timeout(startTime)
for car in self.cars:
# no yield here
env.process(car.move())
class Car():
def __init__(self, env, name, initial_location):
self.env = env
self.name = name
self.location = initial_location
self.path = iter(cycle(["A", "B", "C", "B"]))
def move(self):
# let each car move itself, more like a real car
while True:
print("{} is now at position {}, at time: {}".format(self.name, self.location, env.now))
yield env.timeout(1)
self.location = next(self.path)
env = simpy.Environment()
carA = Car(env, "carA", "A")
carB = Car(env, "carB", "A")
carC = Car(env, "carC", "A")
dispatcher = Dispatch(env, [carA,carB,carC])
env.run(until=20)