我试图依次模拟带有一系列交通信号灯的环形道路。车辆通过泊松过程进入系统。一旦进入系统,它们就会在每盏灯处排队。他们经过一个队列需要一个时间单位。当他们经过多个等于其行程长度的队列时,他们退出系统。队列仅在绿色阶段运行。汽车用整数表示。
问题是,即使代码的这一部分只能通过if语句(检查该双端队列中是否装有汽车)才能到达,但我始终收到错误消息“从空双端队列弹出”。我对simpy不太熟悉,因此我认为问题与超时有关。如果我在弹出操作后将超时时间移到该代码,则该代码有效。但这不是我想要的安静。
{{1}}
答案 0 :(得分:0)
不是解决方法,而是解决方法...
import simpy
from simpy.util import start_delayed
# import numpy.random
from collections import deque,namedtuple
from numpy import random
NUM_INT = 3
ARRIVAL_TIME_MEAN = 1.1
TRIP_LENGTH = 4
GREEN_TIME = 3.0
RED_TIME = 3.0
class Simulation(object):
def __init__(self,env):
self.env = env
self.intersections = [Intersection(env,i) for i in range(NUM_INT)]
for (i,intersection) in enumerate(self.intersections):
intersection.set_next_intersection(self.intersections[(i+1)%NUM_INT])
self.env.process(self.light())
self.env.process(self.arrivals())
def arrivals(self):
while True:
yield self.env.timeout(random.exponential(ARRIVAL_TIME_MEAN))
intersection = random.choice(self.intersections)
intersection.receive(TRIP_LENGTH)
def light(self):
while True:
for intersection in self.intersections:
intersection.start_departing()
yield self.env.timeout(GREEN_TIME)
for intersection in self.intersections:
intersection.turn_red()
yield env.timeout(RED_TIME)
class Intersection(object):
def __init__(self,env,index):
self.index = index
self.queue = deque()
self.env = env
self.start_departing()
def set_next_intersection(self,intersection):
self.next_intersection = intersection
def start_departing(self):
self.is_departing = True
self.action = env.process(self.departure())
def turn_red(self):
if self.is_departing:
self.is_departing = False
self.action.interrupt('red light')
def receive(self,car):
self.queue.append(car)
if not self.is_departing:
self.start_departing()
def departure(self):
while True:
try:
if len(self.queue)==0:
self.is_departing = False
self.env.exit('no more cars in %d'%self.index)
else:
yield self.env.timeout(1.0)
if len(self.queue)>0:
if len(self.queue)==1:
car=self.queue[0]
self.queue.clear()
else:
car = self.queue.popleft()
car = car - 1
if car > 0:
self.next_intersection.receive(car)
except simpy.Interrupt as i:
print('interrupted by',i.cause)
env = simpy.Environment()
sim = Simulation(env)
env.run(until=15.0)
告诉我这是否适合您
答案 1 :(得分:0)
在departure
中,如果队列不为空,则立即屈服,这将使调用进程运行,这可能导致其他事件导致队列为空并引发异常。这有点像协作式多任务处理,但是没有锁,因此您在放置yield
的位置上要格外小心。
将yield
移到if
的末尾可以为我修复。
def departure(self):
while True:
try:
if len(self.queue)==0:
self.is_departing = False
self.env.exit('no more cars in %d'%self.index)
else:
car = self.queue.popleft()
car = car - 1
if car > 0:
self.next_intersection.receive(car)
yield self.env.timeout(1.0)
except simpy.Interrupt as i:
print('interrupted by',i.cause)
yield self.env.timeout(1.0)