Two jobs share one machine. Job one takes four hours, job two takes three, and neither can run while the other is on the machine. Let x₁ and x₂ be the start times. Either job one finishes before job two starts, which is x₁ + 4 ≤ x₂, or job two finishes before job one starts, which is x₂ + 3 ≤ x₁. Exactly one of those must hold.
Definition · Either-or pairGiven two rows A(x) ≤ a and B(x) ≤ b of which at least one must hold, the disjunctive formulation introduces one binary y and writes A(x) ≤ a + M_A(1 − y) together with B(x) ≤ b + M_B y, where each M is large enough to make its own row vacuous over the rest of the feasible region.
Written as ≤ rows, the pair above is x₁ − x₂ ≤ −4 and −x₁ + x₂ ≤ −3. With deadlines putting both start times in [0, 10], the most the first left-hand side can exceed its right-hand side is 10 − 0 − (−4) = 14, so M_A = 14; by the mirror argument M_B = 13. Each constant is the slack its own row needs to become harmless, and not one unit more.
Example · Both branches, solvedMinimise x₁ + x₂. Fixing y = 1 enforces “job one first” and the model starts the jobs at (0, 4), costing 4. Fixing y = 0 enforces “job two first” and starts them at (3, 0), costing 3. Both are genuine schedules, the second is cheaper, and the integer problem wants the better of exactly these two — which is what the binary means.
What the conjunction does, and what the relaxation does
Write both original rows together and add them: the left-hand sides cancel to 0 and the right-hand sides give −7, so the model asserts 0 ≤ −7 and is infeasible. That is the diagnosis to recognise, because the symptom is a solver reporting infeasibility on data that is perfectly consistent, and the usual response is to go looking for a typo in the processing times.
Now leave y continuous. The relaxation sets y = 3/13, starts both jobs at time zero, and reports 0. Every row is satisfied: y is large enough to relax the second row by 3 and small enough to relax the first by 4, so both are half-off at once. The value 0 is a perfectly good lower bound on the integer answer of 3. It is not a schedule, and the machine cannot run two jobs at once because a variable took a value between 0 and 1.
The two constants need not be equal and each must be valid for its own row: here 14 and 13. One M used for both, unchecked, is how a disjunction quietly becomes an implication — if the shared value is big enough for one row and too small for the other, then one branch of the “or” is partially enforced even when the binary says it should be off, and the model answers a question with one alternative half-deleted.
The same pair, repeated over every pair of jobs on every machine, is what makes a job shop an integer programme rather than a linear one. That is why “Scheduling” can prove single-machine rules by exchange arguments and still needs this course the moment two jobs contend for one resource: the sequencing decision is a binary, and there is no linear model of it.
The device generalises past two alternatives. Three rows of which exactly one must hold need three binaries summing to 1, each relaxing its own row by M(1 − y_k); and a two-level capacity — either run at the small size or at the large one — is the same pattern with the two rows being the two capacity limits. What does not generalise is guessing the constants: each one is sized against its own row, every time.