Changeover

A changeover is the time needed to switch a machine from producing one product to another. There are three common ways to model it.

1. In the objective

Charge a cost for each seq[t1, t2] whose products differ. The cost does not appear in the schedule itself, only the cost minimised.

total_co = sum(seq[t1, t2] * changeover_cost[t1, t2] for ...)
model.minimize(make_span + total_co)

Simple, but time and cost are decoupled: the schedule may not leave physical room for the changeover.

Example: example_01_simple_sequence.py.

2. In the precedence constraint

Include the changeover in the gap between tasks:

gap = changeover_time if products_differ(t1, t2) else 0
model.add(end[t1] + gap <= start[t2]).only_enforce_if(seq[t1, t2])

Now time and cost agree: a changeover actually pushes the next task later.

Example: example_04_seq_with_changeover_in_constraint.py.

3. As a first-class event

Create an optional interval for every (t1, t2) that represents the changeover itself. When t1 -> t2 is chosen, the interval is present, sits between the two tasks, and has the right duration.

co_iv = model.new_optional_interval_var(co_start, co_duration, co_end, co_present, ...)
model.add(end[t1] <= co_start).only_enforce_if(seq[t1, t2])
model.add(co_end <= start[t2]).only_enforce_if(seq[t1, t2])
model.add(co_present == 1).only_enforce_if(seq[t1, t2])

This lets you add the changeover interval to add_cumulative (it consumes operator time) or apply cleaning-resource constraints to it.

Example: example_08_changeover_as_event.py.

Starting product

A machine usually begins with some product already loaded. Model it with a dummy task 0 whose "product" is the starting product; the cost from dummy to the first real task is zero if they match, else the usual changeover.

Example: example_02_seq_lock_starting_product.py.