Short note. A compact reference, correct as far as it goes. It will be expanded into a full guide with a worked example and an interactive demonstration.
Problem
The Big-M method works, but picking M is
fragile: too loose and the solver crawls, too tight and you cut off valid
solutions. Modern solvers let you skip the constant entirely.
When to use it
Whenever your solver supports it (Gurobi, CPLEX, and modern OR-Tools CP-SAT all do) and the conditional relationship is a straightforward “if binary, then linear constraint.” It’s strictly better than Big-M when available.
Formulation
Conceptually identical to Big-M, but the solver enforces it directly during branch-and-bound rather than through a relaxed linear inequality:
y = 1 => a^T x <= b
y = 0 => no restriction on x
Code sketch
import gurobipy as gp
from gurobipy import GRB
model = gp.Model()
x = model.addVar(name="x")
y = model.addVar(vtype=GRB.BINARY, name="y")
# If y == 1, enforce x <= 500. No M needed.
model.addGenConstrIndicator(y, True, x <= 500)
Pitfalls
- Indicator constraints are solved via branching, not the LP relaxation — they can still be slow on problems with many conditional rules. Profile before assuming they’re always faster than a well-tuned Big-M.
- Not every open-source solver supports them. Check before committing — falling back to Big-M mid-project is annoying but not hard.
- They express “if
y, then constraint” cleanly, but for genuinely logical combinations (AND/OR/XOR across several binaries) see Logical Constraints.