Multi-stage jobs
A job can consist of several stages that must run in order. Each stage is a task with its own start/end; the job start is the earliest task start and the job end is the latest task end.
Job - stage - task structure
tasks = {(job, stage) for job in jobs for stage in stages}
for job in jobs:
model.add_min_equality(job_start[job], [start[job, s] for s in stages])
model.add_max_equality(job_end[job], [end [job, s] for s in stages])
# stage precedence
for s in sorted(stages)[:-1]:
model.add(end[job, s] <= start[job, s + 1])
Example: example_21_stages_one_job.py.
Stage-level no-overlap
If each stage has a single shared machine, forbid two jobs from sitting on the same stage simultaneously:
for s in stages:
model.add_no_overlap([intervals[job, s] for job in jobs])
Examples: example_22_stages_two_jobs.py,
example_23_multistage_two_jobs_co.py.