I'm trying to model a manufacturing line where some machines depends on specific items produced by other machines and can't start its job until previous ones put the items into their stores.
For example:
We have 4 Machines (A, B, C, D), Machine A
has a Store A*
(B,C,D Stores correspondingly).
Machine A
can start work only if there's an item in Store A*
.
Item in A* consists of three items from B*, C*, D* Stores.
Is there any way to increase count in Store A*
only if Stores B*
, C*
, D*
have at least one item?
You need to use the env.all_of event to wait for a set of events to finish. In this case, 3 get() events from the three ouput queues from 3 machines. see the example
"""
Simple model how one machine does not start until it has multiple inputs
Programmer: Michael R. Gibbs
"""
import simpy
import random
class Entity(object):
pass
def imput_process(env, id_pre, time_func, out_q):
"""
simple loop to generate output entities
to be consumed by the out process
"""
cnt = 0
while True:
yield env.timeout(time_func())
cnt += 1
ent = Entity()
ent.id = id_pre + ' ' + str(cnt)
out_q.put(ent)
print(f'{env.now} made entity {ent.id}')
def out_process(env, a_q, b_q, c_q, time_func):
"""
waits until has a entity from each of the queues
then do some processing
"""
while True:
# make the requests in parrelle
# note no yields here
req_a = a_q.get()
req_b = b_q.get()
req_c = c_q.get()
# now us a all_of to wait for all
# the requests to finish
response = yield env.all_of([req_a, req_b, req_c])
# response is a dict where key is the reqest and value is
# what is what would be returned by a yield to the request
ent_a = response[req_a]
ent_b = response[req_b]
ent_c = response[req_c]
print(f'{env.now} out has entites {ent_a.id}, {ent_b.id}, {ent_c.id}')
yield env.timeout(time_func())
print(f'{env.now} out process completed')
# bootup
env = simpy.Environment()
store_a = simpy.Store(env)
store_b = simpy.Store(env)
store_c = simpy.Store(env)
env.process(imput_process(env, 'A', lambda : random.triangular(1,1,5), store_a))
env.process(imput_process(env, 'B', lambda : random.triangular(1,3,5), store_b))
env.process(imput_process(env, 'C', lambda : random.triangular(1,5,5), store_c))
env.process(out_process(env, store_a, store_b, store_c, lambda : random.triangular(1,2,4)))
env.run(100)