taxi simulator using coroutines

This commit is contained in:
Luciano Ramalho 2015-02-11 20:37:24 -02:00
parent 080addddc7
commit 0327697a15

View File

@ -4,21 +4,23 @@ Taxi simulator
Sample run with two cars, random seed = 4::
>>> main(num_taxis=2, seed=7)
taxi: 0 Event(time=2, actor_id=0, action='pick up passenger')
>>> main(num_taxis=2, seed=10)
taxi: 0 Event(time=0, actor_id=0, action='leave garage')
taxi: 0 Event(time=4, actor_id=0, action='pick up passenger')
taxi: 0 Event(time=10, actor_id=0, action='drop off passenger')
taxi: 1 Event(time=10, actor_id=1, action='leave garage')
taxi: 1 Event(time=11, actor_id=1, action='pick up passenger')
taxi: 1 Event(time=12, actor_id=1, action='drop off passenger')
taxi: 0 Event(time=13, actor_id=0, action='drop off passenger')
taxi: 0 Event(time=15, actor_id=0, action='pick up passenger')
taxi: 0 Event(time=16, actor_id=0, action='drop off passenger')
taxi: 1 Event(time=16, actor_id=1, action='pick up passenger')
taxi: 0 Event(time=17, actor_id=0, action='going home')
taxi: 1 Event(time=24, actor_id=1, action='drop off passenger')
taxi: 1 Event(time=25, actor_id=1, action='pick up passenger')
taxi: 1 Event(time=31, actor_id=1, action='drop off passenger')
taxi: 1 Event(time=32, actor_id=1, action='pick up passenger')
taxi: 1 Event(time=33, actor_id=1, action='drop off passenger')
taxi: 1 Event(time=34, actor_id=1, action='going home')
taxi: 0 Event(time=14, actor_id=0, action='pick up passenger')
taxi: 1 Event(time=28, actor_id=1, action='drop off passenger')
taxi: 0 Event(time=32, actor_id=0, action='drop off passenger')
taxi: 0 Event(time=33, actor_id=0, action='going home')
taxi: 1 Event(time=33, actor_id=1, action='pick up passenger')
taxi: 1 Event(time=35, actor_id=1, action='drop off passenger')
taxi: 1 Event(time=38, actor_id=1, action='pick up passenger')
taxi: 1 Event(time=42, actor_id=1, action='drop off passenger')
taxi: 1 Event(time=44, actor_id=1, action='pick up passenger')
taxi: 1 Event(time=75, actor_id=1, action='drop off passenger')
taxi: 1 Event(time=76, actor_id=1, action='going home')
*** end of events ***
"""
@ -31,7 +33,7 @@ import argparse
DEFAULT_NUMBER_OF_TAXIS = 3
DEFAULT_END_TIME = 80
FIND_PASSENGER_INTERVAL = 4
SEARCH_INTERVAL = 4
TRIP_DURATION = 10
Event = collections.namedtuple('Event', 'time actor_id action')
@ -44,9 +46,9 @@ def compute_delay(interval):
def taxi_process(ident, trips, start_time=0):
"""Yield to simulator issuing event at each state change"""
time = start_time
time = yield Event(start_time, ident, 'leave garage')
for i in range(trips):
prowling_ends = time + compute_delay(FIND_PASSENGER_INTERVAL)
prowling_ends = time + compute_delay(SEARCH_INTERVAL)
time = yield Event(prowling_ends, ident, 'pick up passenger')
trip_ends = time + compute_delay(TRIP_DURATION)
@ -54,7 +56,7 @@ def taxi_process(ident, trips, start_time=0):
yield Event(trip_ends + 1, ident, 'going home')
# BEGIN TAXI_SIMULATOR
class Simulator:
def __init__(self, actors):
@ -62,35 +64,38 @@ class Simulator:
self.actors = dict(actors)
def run(self, end_time):
"""Schedule and execute events until time is up"""
for ident, actor in sorted(self.actors.items()):
first_event = next(actor) # prime each coroutine
self.events.put(first_event)
def run(self, end_time): # <1>
"""Schedule and display events until time is up"""
# schedule the first event for each cab
for _, actor in sorted(self.actors.items()): # <2>
first_event = next(actor) # <3>
self.events.put(first_event) # <4>
# main loop of the simulation
time = 0
while time < end_time:
if self.events.empty():
while time < end_time: # <5>
if self.events.empty(): # <6>
print('*** end of events ***')
break
# get and display current event
current_event = self.events.get()
print('taxi:', current_event.actor_id,
current_event = self.events.get() # <7>
print('taxi:', current_event.actor_id, # <8>
current_event.actor_id * ' ', current_event)
# schedule next action for current actor
actor = self.actors[current_event.actor_id]
time = current_event.time
time = current_event.time # <9>
actor = self.actors[current_event.actor_id] # <10>
try:
next_event = actor.send(time)
next_event = actor.send(time) # <11>
except StopIteration:
del self.actors[current_event.actor_id]
del self.actors[current_event.actor_id] # <12>
else:
self.events.put(next_event)
else:
self.events.put(next_event) # <14>
else: # <15>
msg = '*** end of simulation time: {} events pending ***'
print(msg.format(self.events.qsize()))
# END TAXI_SIMULATOR
def main(end_time=DEFAULT_END_TIME, num_taxis=DEFAULT_NUMBER_OF_TAXIS,
seed=None):
@ -98,7 +103,8 @@ def main(end_time=DEFAULT_END_TIME, num_taxis=DEFAULT_NUMBER_OF_TAXIS,
if seed is not None:
random.seed(seed) # get reproducible results
taxis = {i: taxi_process(i, (i+1)*2, i*10) for i in range(num_taxis)}
taxis = {i: taxi_process(i, (i+1)*2, i*10)
for i in range(num_taxis)}
sim = Simulator(taxis)
sim.run(end_time)
@ -125,34 +131,39 @@ if __name__ == '__main__':
"""
Sample run:
$ clear; python3 taxi_sim.py -s 19
# BEGIN TAXI_SAMPLE_RUN
$ $ clear; python3 taxi_sim.py -t 3 -s 19
taxi: 0 Event(time=0, actor_id=0, action='leave garage')
taxi: 0 Event(time=5, actor_id=0, action='pick up passenger')
taxi: 0 Event(time=13, actor_id=0, action='drop off passenger')
taxi: 0 Event(time=16, actor_id=0, action='pick up passenger')
taxi: 1 Event(time=17, actor_id=1, action='pick up passenger')
taxi: 1 Event(time=10, actor_id=1, action='leave garage')
taxi: 1 Event(time=13, actor_id=1, action='pick up passenger')
taxi: 2 Event(time=20, actor_id=2, action='leave garage')
taxi: 0 Event(time=21, actor_id=0, action='drop off passenger')
taxi: 1 Event(time=21, actor_id=1, action='drop off passenger')
taxi: 1 Event(time=22, actor_id=1, action='pick up passenger')
taxi: 1 Event(time=23, actor_id=1, action='pick up passenger')
taxi: 2 Event(time=23, actor_id=2, action='pick up passenger')
taxi: 1 Event(time=26, actor_id=1, action='drop off passenger')
taxi: 1 Event(time=25, actor_id=1, action='drop off passenger')
taxi: 1 Event(time=27, actor_id=1, action='pick up passenger')
taxi: 2 Event(time=27, actor_id=2, action='drop off passenger')
taxi: 1 Event(time=28, actor_id=1, action='pick up passenger')
taxi: 2 Event(time=29, actor_id=2, action='pick up passenger')
taxi: 1 Event(time=30, actor_id=1, action='drop off passenger')
taxi: 1 Event(time=32, actor_id=1, action='pick up passenger')
taxi: 2 Event(time=33, actor_id=2, action='drop off passenger')
taxi: 2 Event(time=34, actor_id=2, action='pick up passenger')
taxi: 2 Event(time=35, actor_id=2, action='drop off passenger')
taxi: 2 Event(time=36, actor_id=2, action='pick up passenger')
taxi: 1 Event(time=41, actor_id=1, action='drop off passenger')
taxi: 1 Event(time=42, actor_id=1, action='going home')
taxi: 2 Event(time=44, actor_id=2, action='drop off passenger')
taxi: 2 Event(time=46, actor_id=2, action='pick up passenger')
taxi: 2 Event(time=60, actor_id=2, action='drop off passenger')
taxi: 2 Event(time=67, actor_id=2, action='pick up passenger')
taxi: 2 Event(time=73, actor_id=2, action='drop off passenger')
taxi: 0 Event(time=74, actor_id=0, action='drop off passenger')
taxi: 2 Event(time=74, actor_id=2, action='going home')
taxi: 0 Event(time=75, actor_id=0, action='going home')
taxi: 1 Event(time=31, actor_id=1, action='drop off passenger')
taxi: 2 Event(time=31, actor_id=2, action='drop off passenger')
taxi: 1 Event(time=33, actor_id=1, action='pick up passenger')
taxi: 2 Event(time=33, actor_id=2, action='pick up passenger')
taxi: 2 Event(time=36, actor_id=2, action='drop off passenger')
taxi: 2 Event(time=37, actor_id=2, action='pick up passenger')
taxi: 2 Event(time=40, actor_id=2, action='drop off passenger')
taxi: 1 Event(time=42, actor_id=1, action='drop off passenger')
taxi: 1 Event(time=43, actor_id=1, action='going home')
taxi: 0 Event(time=44, actor_id=0, action='pick up passenger')
taxi: 2 Event(time=44, actor_id=2, action='pick up passenger')
taxi: 0 Event(time=49, actor_id=0, action='drop off passenger')
taxi: 0 Event(time=50, actor_id=0, action='going home')
taxi: 2 Event(time=58, actor_id=2, action='drop off passenger')
taxi: 2 Event(time=65, actor_id=2, action='pick up passenger')
taxi: 2 Event(time=71, actor_id=2, action='drop off passenger')
taxi: 2 Event(time=72, actor_id=2, action='going home')
*** end of events ***
# END TAXI_SAMPLE_RUN
"""