Mathematical programming / Linearization

Absolute Value Linearization

Rewrite |x| in an objective or constraint as a pair of linear terms — no binaries required.

Note Beginner

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

You want to penalize deviation from a target — |x - target| — but absolute value isn’t linear.

When to use it

Whenever the absolute value appears in the objective being minimized, or in a constraint of the form |x| <= b. This is one of the few linearization tricks that needs zero extra binary variables.

Formulation

Split x into a positive and negative deviation part:

x = x_pos - x_neg
x_pos >= 0
x_neg >= 0
|x| is replaced by (x_pos + x_neg) in the objective

Minimizing x_pos + x_neg in the objective is enough — the solver will never pay for both simultaneously, so at the optimum one of them is always zero and x_pos + x_neg naturally equals |x|.

Code sketch

import pulp

prob = pulp.LpProblem("min_deviation", pulp.LpMinimize)
x_pos = pulp.LpVariable("x_pos", lowBound=0)
x_neg = pulp.LpVariable("x_neg", lowBound=0)
target = 50

# original variable, reconstructed
x = pulp.LpVariable("x")
prob += x == target + x_pos - x_neg

prob += x_pos + x_neg  # objective: minimize |x - target|

Pitfalls

  • This only works cleanly when you’re minimizing the deviation term (or bounding it above). If you’re maximizing |x|, the solver has an incentive to inflate both x_pos and x_neg — you’ll need binaries or an indicator constraint to force complementarity instead.
  • Don’t forget the reconstruction constraint (x == target + x_pos - x_neg) — it’s easy to drop and end up with an under-constrained model.