微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Simpy 4,同时启动多个进程

如何解决Simpy 4,同时启动多个进程

我使用的是 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,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
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,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,initial_location):
        self.env = env
        self.name = name
        self.location = initial_location
        self.path = cycle(["A","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: {},"A")
cars = [cara,carB]

for car in cars:
    dispatch(env,car)

env.run(until=20)

解决方法

您可以同时使用 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
,

你的第一个密码就快到了

真正的问题是 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,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)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。