I have to simulate a job shop. The steps became available as previous steps are being finished. In the example of the image, you can start steps 1 and 2 right away, but step 3 will only be available after step 1 finished, and so on. The model is graphically represented here: Process flow chart
There are a number of operators that can do the job, but I only want to give them the task once the previous task is finished (I can't do the full schedule all at once).
I am having a hard time trying to inject the next operation in the flow, as this depends on the end of other operations and the availability of resources at that point.
I tried requesting operators for the next step, but it might be that the next step available is not the one I expected, which caused a malfunction.
I tried requesting all operators, using the one that became available and cancel the other requests, but this, in the way I was doing it, causes the simulation to finish early (apparently it expects no more events)
I tried creating a custom event that the operator will succeed when they finished their current task, with a structure like the following:
operation_finished = env.event()
while True:
""" find what operations and operators are available"""
available_operations = check_available_operations()
operators_available = find_any_operator_available()
""" let the scheduler decide if it wants to schedule a next operation. For now,
it always does, so I expect these to be null only when the sequence is finished"""
next_operation = schedule_operation(available_operations, operators_available)
next_operator = schedule_operator(available_operations, operators_available)
""" launch the operation with the operator that we know is available.
This operator will succeed operation_finished once the operation is finished"""
env.process(operator_process(env, operation))
""" If the scheduler did not make a decision or no machine was available,
wait for the next operator to finish"""
if len(next_operator) == 0:
yield operation_finished
print('Whatever is here will never print')
A structure like this only schedules the first and stops when the first it is finished
In simpy you usually do not have a "master" schedular controlling everything. Instead you have a bunch of processes running in parallel, where each task waits for a entity to show up, competes for a resource, take some time for processing, release the resource, and send the entity to its next task. Flow is controlled by competition for limited resources, or limited queue sizes.
Here is a example which has your two flows paths where each task needs a resource from the same resource pool. Requests for resources tend to be first in first out. I'm not sure I fully understood your scenario, but this should still be a good start.