AI Knowledge Tree

Constrained optimization and Lagrange multipliers

Turn an equality-constrained problem into stationarity of a Lagrangian.

Real problems come with constraints: minimize loss subject to a budget, a norm bound, or a physical law. Lagrange multipliers convert a constrained problem into an unconstrained stationarity condition by encoding each constraint with its own variable. The geometry behind it, gradients lining up at the optimum, is the seed of duality and the KKT conditions.

The problem

An equality-constrained problem is

min⁡xf(x)subject tohi(x)=0,i=1,…,m.\min_x f(x) \quad \text{subject to} \quad h_i(x) = 0, \quad i = 1, \dots, m.

The feasible set is the intersection of the constraint surfaces {x:hi(x)=0}\{x : h_i(x) = 0\}. A solution must minimize ff while staying on this set; the unconstrained condition ∇f=0\nabla f = 0 no longer applies, because moving off the surface is not allowed.

The geometric condition

At a constrained minimum x⋆x^\star, you cannot decrease ff by any feasible move. A feasible move is one tangent to the constraint surface, that is, orthogonal to every constraint gradient ∇hi(x⋆)\nabla h_i(x^\star). For no such move to decrease ff, the objective gradient must have no component along the surface: ∇f(x⋆)\nabla f(x^\star) must lie entirely in the span of the constraint gradients.

∇f(x⋆)=∑i=1mλi ∇hi(x⋆)\nabla f(x^\star) = \sum_{i=1}^m \lambda_i\, \nabla h_i(x^\star) [1]

for some scalars λi\lambda_i, the Lagrange multipliers. With one constraint, this says ∇f\nabla f and ∇h\nabla h are parallel: the level set of ff is tangent to the constraint surface at the optimum. If they were not parallel, you could slide along the surface to a lower level set.

The Lagrangian

Package the condition into a single function, the Lagrangian:

L(x,λ)=f(x)−∑i=1mλi hi(x).\mathcal{L}(x, \lambda) = f(x) - \sum_{i=1}^m \lambda_i\, h_i(x).

Its stationarity conditions reproduce the problem exactly. Setting ∇xL=0\nabla_x \mathcal{L} = 0 gives the gradient-alignment condition ∇f=∑iλi∇hi\nabla f = \sum_i \lambda_i \nabla h_i, and setting ∂L/∂λi=0\partial \mathcal{L}/\partial \lambda_i = 0 gives back the constraint hi(x)=0h_i(x) = 0. A constrained problem in nn variables becomes an unconstrained stationarity problem in n+mn + m variables (x,λ)(x, \lambda).

What the multiplier means

The multiplier λi\lambda_i is the sensitivity of the optimal value to the constraint. If the constraint is relaxed to hi(x)=ch_i(x) = c, then

∂f⋆∂c=λi,\frac{\partial f^\star}{\partial c} = \lambda_i, [2]

the shadow price: how much the optimum improves per unit of loosening. A zero multiplier means the constraint is not binding the objective. This economic reading carries directly into the dual variables of the next lesson.

Worked example

Minimize f(x,y)=x2+y2f(x, y) = x^2 + y^2 subject to x+y=1x + y = 1. The Lagrangian is L=x2+y2−λ(x+y−1)\mathcal{L} = x^2 + y^2 - \lambda(x + y - 1). Stationarity: 2x−λ=02x - \lambda = 0, 2y−λ=02y - \lambda = 0, x+y=1x + y = 1. The first two give x=yx = y, the constraint gives x=y=1/2x = y = 1/2, and λ=1\lambda = 1. The closest point on the line to the origin is its foot of perpendicular, confirming the gradient-alignment geometry.

The constrained optimum is where an objective contour just touches the constraint line; there the two gradients are parallel.
The constrained optimum is where an objective contour just touches the constraint line; there the two gradients are parallel.

Check it on arrays

python · numpy
import numpy as np

# min x^2 + y^2 s.t. x + y = 1, solved via the KKT linear system.
# Stationarity + constraint:  [2 0 -1][x]   [0]
#                             [0 2 -1][y] = [0]
#                             [1 1  0][lam]  [1]
M = np.array([[2.0, 0.0, -1.0],
              [0.0, 2.0, -1.0],
              [1.0, 1.0,  0.0]])
rhs = np.array([0.0, 0.0, 1.0])
x, y, lam = np.linalg.solve(M, rhs)
print(f"x={x:.4f}, y={y:.4f}, lambda={lam:.4f}")   # 0.5, 0.5, 1.0

# Shadow price: relax constraint to x + y = 1 + c, optimum f* = (1+c)^2 / 2
# df*/dc at c=0 should equal lambda
c = 1e-5
f_star = lambda cc: (1 + cc)**2 / 2
print("df*/dc:", round((f_star(c) - f_star(-c)) / (2 * c), 4), " lambda:", round(lam, 4))

# Confirm gradient alignment: grad f = lambda * grad h at the optimum
grad_f = np.array([2 * x, 2 * y])
grad_h = np.array([1.0, 1.0])
print("grad f == lambda grad h:", np.allclose(grad_f, lam * grad_h))

Solving the Lagrange system lands on (1/2,1/2)(1/2, 1/2) with multiplier 1, the shadow price matches the multiplier, and the objective and constraint gradients align.

Exercises

Exercise 1. Minimize f(x,y)=x2+4y2f(x, y) = x^2 + 4y^2 subject to x+y=3x + y = 3 using a Lagrangian. Find x⋆,y⋆x^\star, y^\star, and the multiplier λ\lambda.

Solution

Step 1. Form L=x2+4y2−λ(x+y−3)\mathcal{L} = x^2 + 4y^2 - \lambda(x + y - 3). Stationarity in xx and yy gives 2x−λ=02x - \lambda = 0 and 8y−λ=08y - \lambda = 0, so x=λ/2x = \lambda/2 and y=λ/8y = \lambda/8.

Step 2. Impose the constraint x+y=3x + y = 3:

λ2+λ8=4λ+λ8=5λ8=3,soλ=245=4.8.\frac{\lambda}{2} + \frac{\lambda}{8} = \frac{4\lambda + \lambda}{8} = \frac{5\lambda}{8} = 3, \quad\text{so}\quad \lambda = \frac{24}{5} = 4.8.

Step 3. Back-substitute: x=λ/2=2.4x = \lambda/2 = 2.4 and y=λ/8=0.6y = \lambda/8 = 0.6. Check the constraint: 2.4+0.6=32.4 + 0.6 = 3. The optimum is (2.4,0.6)(2.4, 0.6) with λ=4.8\lambda = 4.8, and f⋆=2.42+4⋅0.62=5.76+1.44=7.2f^\star = 2.4^2 + 4 \cdot 0.6^2 = 5.76 + 1.44 = 7.2.

Exercise 2. Verify the shadow-price interpretation for Exercise 1 directly. Relax the constraint to x+y=3+cx + y = 3 + c, find the optimal value f⋆(c)f^\star(c) as a function of cc, and confirm df⋆dc∣c=0=λ\frac{d f^\star}{dc}\big|_{c=0} = \lambda.

Solution

Step 1. With the right-hand side 3+c3 + c, Steps 1 and 2 of Exercise 1 repeat with 33 replaced by 3+c3 + c: the constraint becomes 5λ8=3+c\frac{5\lambda}{8} = 3 + c, so λ=8(3+c)5\lambda = \frac{8(3+c)}{5}, and x=λ/2x = \lambda/2, y=λ/8y = \lambda/8.

Step 2. Then x=4(3+c)5x = \frac{4(3+c)}{5} and y=3+c5y = \frac{3+c}{5}. The optimal value is

f⋆(c)=x2+4y2=16(3+c)225+4⋅(3+c)225=20(3+c)225=4(3+c)25.f^\star(c) = x^2 + 4y^2 = \frac{16(3+c)^2}{25} + 4\cdot\frac{(3+c)^2}{25} = \frac{20(3+c)^2}{25} = \frac{4(3+c)^2}{5}.

Step 3. Differentiate: df⋆dc=8(3+c)5\frac{d f^\star}{dc} = \frac{8(3+c)}{5}, and at c=0c = 0 this is 245=4.8=λ\frac{24}{5} = 4.8 = \lambda. The multiplier is the marginal change in the optimum per unit relaxation, as claimed.

Exercise 3 (code). Solve Exercise 1 by assembling and solving the KKT linear system, then verify the shadow price numerically with a central difference. Every result must match the hand answers (x=2.4x = 2.4, y=0.6y = 0.6, λ=4.8\lambda = 4.8).

Solution
python · numpy
import numpy as np

# min x^2 + 4y^2 s.t. x + y = 3, KKT system:
#  2x        - lam = 0
#         8y - lam = 0
#  x +  y          = 3
M = np.array([[2.0, 0.0, -1.0],
              [0.0, 8.0, -1.0],
              [1.0, 1.0,  0.0]])
rhs = np.array([0.0, 0.0, 3.0])
x, y, lam = np.linalg.solve(M, rhs)

assert np.allclose([x, y, lam], [2.4, 0.6, 4.8])

# Shadow price by central difference of f*(c) = 4(3+c)^2 / 5
f_star = lambda c: 4 * (3 + c)**2 / 5
c = 1e-5
slope = (f_star(c) - f_star(-c)) / (2 * c)
assert np.isclose(slope, lam, atol=1e-4)
print(f"x={x}, y={y}, lambda={lam}, df*/dc={slope:.4f}")

The KKT solve recovers (2.4,0.6)(2.4, 0.6) with λ=4.8\lambda = 4.8, and the numerical slope of the optimal value matches the multiplier.

The next lesson generalizes the Lagrangian into a dual problem with its own optimization.


References

  1. [1]Bertsekas, D. P. (1999). Nonlinear Programming (2nd ed.), §3.1. Athena Scientific. The Lagrange multiplier theorem for equality-constrained problems.↩
  2. [2]Boyd, S., & Vandenberghe, L. (2004). Convex Optimization, §5.6. Cambridge University Press. The sensitivity (shadow-price) interpretation of the multipliers.↩