simpy
simpy copied to clipboard
Support one resource with one queue?
Hello~ Can simpy support that each resource has one or more queue? Specifically, I want to model many ATMs, and each ATM has one queue. I know simpy can model all ATMs with only one queue. So could you help me?
It is better that each resource has more queues and I can choose which queue to be served.
Hi @JinJinGuang
Could you clarify your use-case, since I really get two out of your message?
(1) One resource with multiple queues (e.g., one ATM with many queues, which would require a "queue selection" algorithm). (2) n resources each with its own queue (e.g., 10 ATMs with separate queues).
@cristiklein
Yes. Both are needed. Case (2) is what I need now. And I want to use Case (1) in other situations in the future.
Hope you can help me. Thanks a lot.
For case (2), I would simply create n resources.
For case (1), I would create one process per queue and a process that aggregates all queues and decides which one to submit to the resource.
If you have some existing code, I could highlight how to do the adaptation.
Thank you very much. I will try it.
Hi @cristiklein
I can deal with case (2), but have problems in case (1). Hope you can help me to highlight how to do the adaptation.
import random
import numpy as np
import simpy
class Customer(object):
def __init__(self, env, name):
self.name = name
self.env = env
self.arrive = env.now
self.wait = None
print('%7.4f %s: Here I am' % (self.arrive, self.name))
def go2bank(self, bank):
with bank.machine.request() as request:
yield request
self.wait = env.now - self.arrive
print('%7.4f %s: Waited %6.3f' % (env.now, self.name, self.wait))
yield env.process(bank.serve(self))
print('%7.4f %s: Finished' % (env.now, self.name))
class Bank(object):
def __init__(self, env, num_machines, servetime):
self.env = env
self.machine = simpy.Resource(env, capacity=num_machines)
self.servetime = servetime
def serve(self, customer):
yield self.env.timeout(self.servetime)
class Source(object):
def __init__(self, number, arrival_rate):
self.num = number
self.arrival_rate = arrival_rate
def generator(self, env, bank):
for i in range(self.num):
c = Customer(env, 'Customer%02d' % i)
env.process(c.go2bank(bank))
t = random.expovariate(1.0 / self.arrival_rate)
yield env.timeout(t)
RANDOM_SEED = 42
NEW_CUSTOMERS = 5 # Total number of customers
INTERVAL_CUSTOMERS = 2 # Generate new customers roughly every x seconds
NUM_MACHINE = 2
SERVE_TIME = 4
# Setup and start the simulation
print('ATM')
random.seed(RANDOM_SEED)
env = simpy.Environment()
# Start processes and run
bank = Bank(env, NUM_MACHINE, SERVE_TIME)
source = Source(NEW_CUSTOMERS, INTERVAL_CUSTOMERS)
env.process(source.generator(env, bank))
env.run()
I'm confused how to deal with with bank.machine.request() as request:
and how to create one process per queue and a process that aggregates all queues and decides which one to submit to the resource. Thanks a lot.
Hi,
I just ran your code and it looks good to me. Do I understand correctly that you want to simulated one (common) queue for two machines? If yes, then your code looks good. Customers seem to be served in first-come-first-serve order as expected.
Were you expecting a different order?
În vin., 13 sept. 2019 la 12:35, JinJinGuang [email protected] a scris:
Hi @cristiklein https://github.com/cristiklein
I can deal with case (2), but have problems in case (1). Hope you can help me to highlight how to do the adaptation.
import random import numpy as npimport simpy class Customer(object): def init(self, env, name): self.name = name self.env = env self.arrive = env.now self.wait = None print('%7.4f %s: Here I am' % (self.arrive, self.name))
def go2bank(self, bank): with bank.machine.request() as request: yield request self.wait = env.now - self.arrive print('%7.4f %s: Waited %6.3f' % (env.now, self.name, self.wait)) yield env.process(bank.serve(self)) print('%7.4f %s: Finished' % (env.now, self.name))
class Bank(object): def init(self, env, num_machines, servetime): self.env = env self.machine = simpy.Resource(env, capacity=num_machines) self.servetime = servetime
def serve(self, customer): yield self.env.timeout(self.servetime)
class Source(object): def init(self, number, arrival_rate): self.num = number self.arrival_rate = arrival_rate
def generator(self, env, bank): for i in range(self.num): c = Customer(env, 'Customer%02d' % i) env.process(c.go2bank(bank)) t = random.expovariate(1.0 / self.arrival_rate) yield env.timeout(t)
RANDOM_SEED = 42NEW_CUSTOMERS = 5 # Total number of customersINTERVAL_CUSTOMERS = 2 # Generate new customers roughly every x secondsNUM_MACHINE = 2SERVE_TIME = 4
Setup and start the simulationprint('ATM')
random.seed(RANDOM_SEED) env = simpy.Environment()
Start processes and run
bank = Bank(env, NUM_MACHINE, SERVE_TIME) source = Source(NEW_CUSTOMERS, INTERVAL_CUSTOMERS) env.process(source.generator(env, bank)) env.run()
I'm confused how to deal with with bank.machine.request() as request: and how to create one process per queue and a process that aggregates all queues and decides which one to submit to the resource. Thanks a lot.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/cristiklein/simpy/issues/6?email_source=notifications&email_token=AAMVPIKD3GC3PMKEV3ITUPDQJNUG7A5CNFSM4IVOBGR2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD6UUTKQ#issuecomment-531188138, or mute the thread https://github.com/notifications/unsubscribe-auth/AAMVPIOC4YJLL6LTE22SRLLQJNUG7ANCNFSM4IVOBGRQ .
-- Cristian Klein
Hi, @cristiklein
My code is to solve case(2), but I still want to solve case(1).
I want to modify the code, but don't know how to do what you said before:
For case (1), I would create one process per queue and a process that aggregates all queues and decides which one to submit to the resource.