#python #simpy
Вопрос:
Я хочу смоделировать систему такси-пассажир. Есть C стоянок такси, где такси и пассажиры могут встретиться там перед отъездом. Поскольку есть очереди как из такси, так и из пассажиров, я подумываю об использовании магазина с емкостью = C, где пассажиры выдают запросы «получить», а такси выдают запросы «поместить».
Однако запрос «получить», по-видимому, берет ресурс (такси) сразу из магазина. Как я могу справиться с совпадением времени в этой ситуации?
Например, если есть 2 точки доступа, процесс будет выглядеть примерно так
0.00 Passenger 0 arrives
0.10 Passenger 1 arrives
0.11 Taxi 0 arrives
0.11 Passenger 0 is matching with Taxi 0
0.15 Passenger 2 arrives
0.16 Taxi 1 arrives
0.16 Passenger 1 is matching with Taxi 1
0.17 Taxi 2 arrives (and wait in the queue because 2 access points are occupied)
0.20 Passenger 0 and Taxi 0 finish and leave the system
0.20 Passenger 2 is matching with Taxi 2
Комментарии:
1. не уверен, что я понимаю проблему, не могли бы вы добавить более подробный пример?
Ответ №1:
Я предполагаю, что вы хотите, чтобы такси потреблялось по одному за раз. Однако, если у пула ресурсов есть ресурсы, он немедленно выполнит все запросы. Таким образом, если три пассажира запрашивают такси одновременно, а в пуле ресурсов есть три такси, то все три запроса будут заполнены одновременно.
Если вы хотите, чтобы такси использовалось по одному за раз, вам нужно добавить привратника. В данном случае это была бы стоянка такси, часто это торговые прилавки.
Стоянка такси — это пул ресурсов из одного ресурса. Ресурс представляет собой главу очереди. Когда пассажиры прибывают, они запрашивают главу очереди, если кто-то еще уже стоит во главе очереди, пассажир выстраивается в очередь и ждет своей очереди. Как только пассажир становится во главе очереди, он заказывает такси в вашем магазине такси. Если магазин такси пуст, то придется еще раз подождать, пока такси вернется. Обратите внимание, что пассажир не освобождает руководителя очереди на стоянку такси до тех пор, пока его запрос на такси не будет фактически заполнен. Также обратите внимание, что пассажиру необходимо вернуть такси в магазин такси после того, как пассажир закончит с такси
посмотрите на мой пример
"""
simulation of passengers waiting for taxis at a taxi stand
Passengers first wait to be first in line to seize the taxi stand
Then they wait for the next taxi
There is a short delay as the passenger gets into to taxi
before the passenger releases the the taxi stand, allowing
the next passenger to wait for the next taxi
When the sim start, the taxi stand will have a queue of taxi
that will be eventualy depleted by the arriving passengers
as the passengers arrive faster then the taxi can server
programmer Michael R. Gibbs
"""
import simpy
from random import randint
class IdClass():
"""
quick class that generates unique id's
for each object created
"""
nextId = 1
def __init__(self):
self.id = type(self).nextId
type(self).nextId =1
class Passenger(IdClass):
"""
Passenger waiting for a taxi
"""
class Taxi(IdClass):
"""
Taxi is the resource passengers are competing for
"""
def getTaxi(env, passenger, taxiStand, taxiQueue):
"""
passenger waits for cab
then takes cap for a trip
Taxi returns after trip
"""
# get in line at the taxi stand
with taxiStand.request() as turnReq:
print(f'{env.now} passenger {passenger.id} has entered taxi stand queue')
yield turnReq
# first in line, now wait for taxi
print(f'{env.now} passenger {passenger.id} is waiting for taxi')
taxi = yield taxiQueue.get()
# got taxi, tine to get into cab
print(f'{env.now} passenger {passenger.id} has taken taxi {taxi.id}')
yield env.timeout(2)
# now cab leaves and taxi stand is free for next passenger
# leave stand and use taxit
print(f'{env.now} taxi {taxi.id} has left')
yield env.timeout(randint(10,60))
# taxi returns for next passenger
yield taxiQueue.put(taxi)
print(f'{env.now} taxi {taxi.id} has return')
def genPassengers(env, taxiStand, taxiQueue):
"""
generates arriving passengers and kicks off their taxi use
"""
while True:
yield env.timeout(randint(1,15))
env.process(getTaxi(env,Passenger(), taxiStand, taxiQueue))
# create simulation
env = simpy.Environment()
# start taxiStand
taxiStand = simpy.Resource(env, capacity=1)
# start taxi queue with 5 taxies
taxiQueue = simpy.Store(env) # unlimited capacity
taxiQueue.items = [Taxi() for _ in range(5)]
# start taxi stand with a queue of 3 passengers
for _ in range(3):
env.process(getTaxi(env, Passenger(),taxiStand,taxiQueue))
# start generating passengers
env.process(genPassengers(env,taxiStand,taxiQueue))
# start sim
env.run(until = 100)
Комментарии:
1. Я действительно сожалею об этом запоздалом ответе. Что я имел в виду, говоря «есть очереди как из такси, так и из пассажиров», так это то, что эта очередь двусторонняя. Как пассажиры, так и такси прибывают в систему и сопоставляются друг с другом, а затем покидают систему без рассмотрения вопроса о возвращении такси. Вот почему я подумал, что это похоже на магазин с get/put.
2. Я думаю, что вы можете сделать :вывести store1.get() и store2.get (), которые будут ждать, пока оба завершатся, прежде чем перейти к следующей строке кода. Это то, что вы ищете?
3. посмотрел ваш первоначальный пост. Итак, когда такси 2 и пассажир 2 совпадут?
4. Такси 2 и Пассажир 2 начнут совпадать, как только одно из пар Такси 0-Пассажир 0 или Такси 1-Пассажир 1 завершит совпадение и покинет стоянку такси. Можете ли вы подробнее рассказать об этой идее в своем предыдущем комментарии? Я думаю, что у меня его нет…
5. измените taxiStand = simpy.Resource(env, емкость=1) на taxiStand = simpy.Resource(env, емкость=2)