Unis
Unis

Reputation: 824

Simpy: Block resource beyond its servicing a user

Consider a carwash as described in the Simpy example list. Now assume that each time a car is serviced, the corresponding washing unit has to be serviced itself, before it can clean the next car. Meanwhile, the serviced car can leave.

How would I best model the above? My current solution is to have "ghost cars" with a high priority that block the carwash during the regeneration time. I don't find this solution very elegant, and guess there is a better way.

In the below example, which represents a poor copy of the above-mentioned tutorial, the serviced car cannot leave the pump during the regeneration period. How could I fix that to mimic the intended behavior? I guess the solution is straightforward; I just don't see it.

import random
import simpy

RANDOM_SEED = 42
NUM_MACHINES = 2  # Number of machines in the carwash
WASHTIME = 5      # Minutes it takes to clean a car
REGENTIME = 3
T_INTER = 7       # Create a car every ~7 minutes
SIM_TIME = 20     # Simulation time in minutes


class Carwash(object):
    def __init__(self, env, num_machines, washtime):
        self.env = env
        self.machine = simpy.Resource(env, num_machines)
        self.washtime = washtime

    def wash(self, car):
        yield self.env.timeout(WASHTIME)
        print("Carwash removed %s's dirt at %.2f." % (car, env.now))

    def regenerateUnit(self):
        yield self.env.timeout(REGENTIME)
        print("Carwash's pump regenerated for next user at %.2f." % (env.now))


def car(env, name, cw):
    print('%s arrives at the carwash at %.2f.' % (name, env.now))
    with cw.machine.request() as request:
        yield request

        print('%s enters the carwash at %.2f.' % (name, env.now))
        yield env.process(cw.wash(name))

        yield env.process(cw.regenerateUnit())

        print('%s leaves the carwash at %.2f.' % (name, env.now))


def setup(env, num_machines, washtime, t_inter):
   # Create the carwash
    carwash = Carwash(env, num_machines, washtime)

    # Create 4 initial cars
    for i in range(4):
        env.process(car(env, 'Car %d' % i, carwash))

    # Create more cars while the simulation is running
    while True:
        yield env.timeout(random.randint(t_inter - 2, t_inter + 2))
        i += 1
        env.process(car(env, 'Car %d' % i, carwash))


# Setup and start the simulation
random.seed(RANDOM_SEED)  # This helps reproducing the results

# Create an environment and start the setup process
env = simpy.Environment()
env.process(setup(env, NUM_MACHINES, WASHTIME, T_INTER))

# Execute!
env.run(until=SIM_TIME)

Thanks a lot in advance.

Upvotes: 0

Views: 257

Answers (1)

Stefan Scherfke
Stefan Scherfke

Reputation: 3232

What you want is to model an entity that uses your resource with a very high priority so that normal entities meanwhile cannot use it. So your "ghost car" is actually not such a bad idea.

Upvotes: 1

Related Questions