What problem does this solve?
Real decision models are full of things that are not linear: “if we open the plant, pay the fixed cost,” “use at most one of these suppliers,” “the cost per unit drops after 1,000 units,” “minimize the worst-case lateness,” “the product of two yes/no decisions.” Mixed-integer linear programming (MILP) solvers are extraordinarily good, but they only accept linear objectives and constraints over continuous and integer variables.
Linearization is the set of exact reformulations that bridge the gap. Each pattern introduces auxiliary variables and linear constraints whose feasible solutions correspond one-to-one with the original nonlinear logic.
When should you use it?
- The nonlinearity involves binary or integer decisions: products, logic, fixed costs, either-or conditions. These linearize exactly.
- The nonlinear function is convex in a minimization (or concave in a maximization) and piecewise linear: maxima, absolute values, increasing marginal costs. These linearize exactly with no extra binaries.
- The function is nonlinear and non-convex but can be approximated by pieces to acceptable accuracy, at the price of extra binaries.
Prefer a native solver feature when one exists (indicator constraints, SOS2, general constraints like max or abs in modern solvers). They often presolve better than a hand-written big-M.
Mathematical formulation
The core patterns, with binary and continuous with known bounds :
Product of two binaries, :
Binary times bounded continuous, (exact McCormick envelope):
Fixed charge (pay if any quantity is produced):
Conditional constraint (big-M: enforce only when ):
Absolute value in a minimization, :
Min-max (minimize the worst of several linear terms):
Logic over binaries. “At most one”: . “If A then B”: . “A or B”: . “Exactly ”: .
Piecewise linear cost with breakpoints : write , cost , , , with at most two adjacent nonzero (an SOS2 condition, or binaries per segment). If is convex in a minimization, the adjacency condition can be dropped.
Intuition
Every linearization is the same move: name the nonlinear quantity as a new variable, then fence it in with linear constraints that are tight exactly where the logic says it should be.
For with binaries, the four constraints describe the convex hull of the four points . The LP relaxation is as tight as it can be, which is why this linearization is “free.”
Big-M is different. It is exact for integer solutions but weak in the LP relaxation when is large, because fractional can switch the constraint mostly off. That is why the size of is a modeling decision, not a constant: use the smallest valid bound you can derive from the data.
The convex cases (absolute value, max in a minimization) need no binaries at all, because the solver is pushing down onto the largest of the terms anyway.
Worked example
A plant can run a product line or not. Running costs a fixed $5,000 and $12 per unit, capacity is 800 units, and if it runs it must produce at least 200 units (a minimum batch). Demand must be met from this line or bought from a supplier at $20 per unit.
Let be “run the line,” the units produced, the units bought:
The single constraint pair encodes three rules at once: no production unless the line runs, at least the minimum batch if it does, and never more than capacity. Producing saves $8 per unit against buying, so running pays when , that is, above 625 units of demand. For the model buys all 500 ($10,000 against $11,000 for running); for it runs and makes 700 ($13,400 against $14,000).
Python implementation
Written with scipy.optimize.milp, which ships with SciPy and needs no separate solver install:
import numpy as np
from scipy.optimize import milp, LinearConstraint, Bounds
def plan(d):
# variables: [y, q, s]
c = np.array([5000.0, 12.0, 20.0])
A = np.array([
[0.0, 1.0, 1.0], # q + s >= d
[-800.0, 1.0, 0.0], # q - 800 y <= 0 (no production unless running; capacity)
[200.0, -1.0, 0.0], # 200 y - q <= 0 (minimum batch if running)
])
cons = LinearConstraint(A, lb=[d, -np.inf, -np.inf], ub=[np.inf, 0.0, 0.0])
res = milp(c, constraints=cons, integrality=[1, 0, 0],
bounds=Bounds([0, 0, 0], [1, np.inf, np.inf]))
y, q, s = res.x
return round(y), round(q), round(s), res.fun
for d in (500, 700):
print(d, plan(d)) # 500 -> (0, 0, 500, 10000.0); 700 -> (1, 700, 0, 13400.0)
The same model in Pyomo, PuLP, gurobipy, or OR-Tools differs only in syntax; the linearization is identical.
Interactive demonstration
A MILP Formulation Explorer that lets you toggle constraints and watch the LP relaxation and integer optimum move is planned for the playground. The Optimization page has a one-page guide to deciding whether linear or integer programming fits your problem at all.
Computational complexity and trade-offs
- Every binary can double the search space. Branch and bound explores far fewer nodes than in practice, but tight formulations matter enormously.
- Tightness beats compactness. A formulation with more constraints but a tighter LP relaxation usually solves faster than a compact one with big-M constraints.
- Big-M size drives both relaxation weakness and numerical trouble. Values like against coefficients near 1 invite tolerance errors where quietly activates a constraint.
- Piecewise approximations trade accuracy for binaries: more breakpoints, more accurate, slower.
Common mistakes
- One giant M for every constraint. Derive a separate, tight bound per constraint from the data.
- Linearizing a convex term with binaries when the plain epigraph constraints would do.
- Linearizing a non-convex maximum in a minimization with only ; that models the maximum correctly only when the objective pushes down.
- Forgetting the lower fence. and alone let the solver set even when both are 1, if it has a reason to.
- Hand-coding what the solver already supports. Indicator constraints and SOS2 sets are often handled better natively.
The individual techniques have their own notes: big-M, absolute value, min-max, indicator constraints, logical constraints, and piecewise-linear approximation.
Related patterns
Big-M Method
Turn an "if this binary is on, then this constraint applies" rule into a linear constraint MILP solvers can handle directly.
Absolute Value Linearization
Rewrite |x| in an objective or constraint as a pair of linear terms — no binaries required.
Min/Max Linearization
Represent max(a, b) or min(a, b) as auxiliary variables and linear constraints so they can appear in a MILP.
Indicator Constraints
Express "if binary y = 1, then constraint C holds" natively, without hand-tuning a Big-M constant.
Logical Constraints (AND / OR / XOR)
Encode boolean logic between binary decisions — "at least one of", "exactly one of", "not both" — as linear constraints.
Piecewise Linear Approximation
Approximate a nonlinear cost or production curve with connected line segments so a linear/MILP solver can still optimize over it.
Mixed-integer linear programming
Add integrality to model yes/no decisions, setups, and discrete quantities.
Branch and bound
How MILP solvers prove optimality: relax, branch, and prune with bounds.