The KKT system#
KKT says that at a constrained optimum the objective gradient is a non-negative combination of the active constraint gradients. Inactive constraints carry zero multiplier — that is complementary slackness, and it is what makes the system solvable.
The Karush–Kuhn–Tucker (KKT) conditions are the generalisation of "set the derivative to zero" to constrained problems. For the primal
with differentiable , the KKT conditions are:
-
Stationarity: , i.e.,
-
Primal feasibility: ,
-
Dual feasibility: (inequality multipliers nonnegative; equality multipliers unrestricted)
-
Complementary slackness:
Together, these four conditions are necessary for a local minimum when a constraint qualification holds, and sufficient under convexity (if and are convex, affine, then any KKT point is a global minimum).
Why four parts? Each plays a distinct role:
- Stationarity says the gradient of the objective is balanced by a linear combination of constraint gradients — constraints "push back" against the objective.
- Primal feasibility says the point must actually satisfy the constraints.
- Dual feasibility locks the sign of inequality multipliers (penalties can only push inward from the boundary).
- Complementary slackness says at most one of and can be nonzero: if a constraint is slack (), its multiplier must be zero; if the multiplier is positive, the constraint must be active ().
Complementary slackness#
The product encodes the logic: an inactive constraint does not participate in stationarity. If , then and vanishes from the stationarity equation. The constraint is invisible to optimality — which makes intuitive sense: if you are inside the feasible region away from the boundary, the wall does not affect where you stand.
Conversely, if , then — the constraint is binding. The positive multiplier indicates the constraint is "pushing back" against the objective: relaxing it would allow the objective to decrease.
Worked numeric example. Consider
Rewrite in standard form:
Lagrangian: .
Stationarity:
From the geometry (smallest circle touching the line in the right half-plane), the solution is . At this point:
- (active), so
- (inactive), so complementary slackness forces
With , stationarity gives , so . The multiplier is positive, confirming is binding. All KKT conditions satisfied.
Worked QP#
A quadratic program (QP) exposes all four KKT parts cleanly:
with (convex QP). The Lagrangian:
Stationarity: (if ).
The KKT conditions reduce to solving for :
This is a linear complementarity problem (LCP) — a mixed system of equations and inequalities. IPM solvers (Week 6) solve essentially this system for successively relaxed complementarity.
Worked 2D QP:
In standard form: , (inequality only, no equalities). , .
At the unconstrained optimum , the constraint is active, is slack (). Complementary slackness: possible, since .
Stationarity: , and similarly .
With : , . At , — all multipliers zero. The constraint is active at (that is exactly ) but has a degenerate zero multiplier: the objective's gradient already points away from the boundary, so the constraint does not participate in stationarity. The unconstrained optimum is feasible, so it is the constrained optimum — complementary slackness is satisfied, but this is degeneracy ( with ), not a slack constraint.
Sensitivity / shadow prices#
Interpretation. The optimal dual variable equals the rate of change of the optimal value when the -th constraint bound is perturbed:
More precisely, for the perturbed problem , under suitable conditions:
The sign convention matters: for in the standard form, tightening the constraint (making more negative) increases the optimal value, so the derivative is positive and equals .
Shadow price intuition. If , the -th constraint is not binding — relaxing or tightening it by a small amount has no first-order effect on the optimum. If is large, the constraint is expensive: the optimal value is highly sensitive to that constraint's location. In engineering design, shadow prices tell you where to spend resources: relax the constraint with the largest multiplier for the biggest payoff.
Worked example — Factory production.
A simplified production problem: (maximise profit) subject to (labour), (materials), .
Solving: the optimum is at , . Both labour and materials constraints are active. Solving the KKT system gives the dual variables (labour), (materials). Interpretation: one extra unit of labour would increase profit by about \0.33$1.33$. The materials constraint is the bottleneck.
What can go wrong#
KKT is a powerful tool but has sharp edges:
-
CQ failure. Without a constraint qualification, KKT may not hold at a local minimum. The example from Week 1 illustrates this: the minimum exists but no finite multiplier satisfies stationarity because .
-
Nonconvex KKT points. KKT conditions are necessary but not sufficient for nonconvex problems. A point can satisfy all four KKT conditions and still be a saddle or a local maximum. Always check second-order conditions or problem structure.
-
Multiple KKT solutions. Nonconvex problems can have many KKT points — each corresponds to a local minimum, maximum, or saddle. Numerical solvers find a KKT point; which one depends on initialisation.
-
Degeneracy. When active constraint gradients are nearly linearly dependent, the LICQ is barely satisfied, and the KKT system becomes ill-conditioned. Solvers report this as "numerical difficulties" or "near-degeneracy."
Knowledge Check#
Complementary slackness requires that for each inequality constraint j, the product λⱼ · hⱼ(x*) equals ____.
Which KKT condition is violated if λⱼ = −2 for an inequality constraint hⱼ(x) ≤ 0?
Browser lab#
Consider the small QP: subject to , . Compute the KKT residual at candidate points and verify the true KKT point .
import numpy as np
def kkt_residual(x, y, lam1, lam2):
"""Compute violations of the four KKT conditions for:
min 0.5*(x^2 + y^2) s.t. 2 - x - y <= 0, -x <= 0
Lagrangian: L = 0.5*(x^2 + y^2) + lam1*(2 - x - y) + lam2*(-x)
"""
# Stationarity
stat_x = x - lam1 - lam2
stat_y = y - lam1
stat = np.sqrt(stat_x**2 + stat_y**2)
# Primal feasibility (negative means satisfied for <= 0)
h1 = 2 - x - y
h2 = -x
primal_viol = max(0, h1) + max(0, h2)
# Dual feasibility
dual_viol = max(0, -lam1) + max(0, -lam2)
# Complementary slackness
comp_viol = abs(lam1 * h1) + abs(lam2 * h2)
return {
"stationarity": stat,
"primal_violation": primal_viol,
"dual_violation": dual_viol,
"complementarity_violation": comp_viol,
"total": stat + primal_viol + dual_viol + comp_viol
}
# Test candidate points
candidates = [
("(0, 0) [infeasible]", 0.0, 0.0, 0.0, 0.0),
("(1, 1) [KKT]", 1.0, 1.0, 1.0, 0.0),
("(2, 0) [feasible, non-optimal]", 2.0, 0.0, 1.0, 0.0),
("(1, 1) [wrong lam]", 1.0, 1.0, 0.0, 0.0),
("(0.5, 1.5) [feasible]", 0.5, 1.5, 0.5, 0.0),
]
print(f"{'Point':<28s} {'stat':>8s} {'primal':>8s} {'dual':>8s} {'comp':>8s} {'total':>8s}")
print("-" * 70)
for name, x, y, l1, l2 in candidates:
res = kkt_residual(x, y, l1, l2)
print(f"{name:<28s} {res['stationarity']:8.4f} {res['primal_violation']:8.4f} "
f"{res['dual_violation']:8.4f} {res['complementarity_violation']:8.4f} "
f"{res['total']:8.4f}")
# Verify KKT point
print(f"\nTrue KKT point: (1, 1) with lam = (1, 0)")
true_res = kkt_residual(1, 1, 1, 0)
print(f"Total KKT residual at true optimum: {true_res['total']:.2e}")
print("Notice: the total KKT residual is exactly 0.00e+00 at (1,1) with λ = (1,0), and ≥ 1.0 at every other test point.")
Key takeaways#
- The KKT system is four conditions: stationarity, primal feasibility, dual feasibility, and complementary slackness.
- Complementary slackness says an inactive constraint does not participate in stationarity; a positive multiplier means the constraint binds.
- For a convex problem with a constraint qualification, KKT is necessary and sufficient for global optimality.
- The optimal multiplier is a shadow price: , the marginal value of relaxing that constraint.
- A zero multiplier means the constraint has no first-order effect; the largest multiplier marks the bottleneck where resources should go.
- KKT has sharp edges — a failing CQ, nonconvex KKT points, multiple solutions, and degeneracy all break naive use.
Further reading#
- Stephen Boyd & Lieven Vandenberghe, Convex Optimization (Cambridge University Press, 2004) — the KKT conditions and the sensitivity/shadow-price interpretation.
- Jorge Nocedal & Stephen Wright, Numerical Optimization (2nd ed., Springer, 2006) — the theory of constrained optimisation, including degeneracy.
- Dimitri P. Bertsekas, Nonlinear Programming (3rd ed., Athena Scientific, 2016) — the fullest treatment of constraint qualifications.
Reading is free. PDF and ePub unlock with the newsletter. Join once and every lesson opens in this browser.