Linear Programming
π‘ Why It Matters
Linear programming (LP) is the foundation of mathematical optimization. It powers resource allocation in supply chains, portfolio construction in finance, scheduling in operations research, and constraint satisfaction in AI planning. Any problem expressible as minimizing a linear objective subject to linear constraints is an LP β and solving LPs efficiently is one of the most impactful achievements in computational mathematics.
βΉοΈ Historical Context
George Dantzig invented the simplex method in 1947. LP was used for logistics planning in WWII and later became central to industrial optimization. Today, LP solvers handle problems with millions of variables in seconds.
Linear Programming Standard Form
DfLinear Program
A linear program is an optimization problem of the form: minimize a linear objective function subject to linear inequality and equality constraints, with non-negative decision variables. The feasible region β the set of all satisfying all constraints β is a convex polytope.
LP Standard Form (Minimization)
Here,
- =Cost (objective) vector in ββΏ
- =Decision variable vector in ββΏ
- =m Γ n constraint coefficient matrix
- =Right-hand side vector in βα΅ (b β₯ 0)
LP Standard Form (Maximization)
Here,
- =Profit (objective) vector
- =Constraint matrix
- =Resource availability vector
β οΈ Conversion to Standard Form
To convert any LP to standard minimization form:
- Maximize β Minimize: Replace with .
- Equality constraints: Replace with and .
- Unrestricted variables: Replace (free) with where .
- β₯ constraints: Multiply by to convert to β€ form.
ThFundamental Theorem of Linear Programming
If an LP has an optimal solution, it has one at a vertex (extreme point) of the feasible polytope. If the feasible region is unbounded and the objective is unbounded below, the LP is infeasible in the bounded direction. If the feasible region is empty, the LP is infeasible.
Geometry of Linear Programs
DfFeasible Region
The feasible region of an LP is the intersection of half-spaces defined by the constraints. It is a convex polytope (possibly unbounded). Since both the objective and constraints are linear, the optimum is always attained at a vertex or along a face of the polytope.
DfVertex (Extreme Point)
A point in a convex set is an extreme point (vertex) if it cannot be expressed as a convex combination of two distinct points in , i.e., there do not exist with and for .
πProblem: Identifying Feasible Region
Find the feasible region and corner points for: maximize subject to , , , .
π‘Solution
The constraints define a polygon with vertices: , , , , . Evaluate the objective: , , , , . Maximum is at .
Simplex Method
DfSimplex Method
The simplex method is an iterative algorithm that moves along edges of the feasible polytope from one vertex to an adjacent vertex, improving the objective at each step. It terminates when no adjacent vertex improves the objective (optimality) or detects an unbounded direction.
DfBasic Feasible Solution (BFS)
A basic feasible solution corresponds to a vertex of the feasible region. It is obtained by setting variables (non-basic) to zero and solving the remaining equations for the basic variables. The BFS is feasible if all basic variables are non-negative.
ThSimplex Optimality Criterion
In a simplex tableau, the current BFS is optimal if all reduced costs (for minimization). If any , the corresponding non-basic variable can enter the basis to improve the objective.
βΉοΈ Simplex Steps
- Initialize: Find an initial BFS (possibly via artificial variables / Big-M / two-phase method).
- Pricing: Select a non-basic variable with negative reduced cost to enter the basis.
- Ratio Test: Determine the leaving variable by the minimum ratio .
- Pivot: Perform a pivot operation to update the tableau.
- Terminate: When no entering variable exists (optimal) or no leaving variable exists (unbounded).
Simplex Ratio Test
Here,
- =Pivot column entry for row i
- =Current RHS value for row i
- =Maximum step size before a basic variable hits zero
import numpy as np
def simplex(c, A, b):
"""Simplex method for: min c^T x, s.t. Ax <= b, x >= 0."""
m, n = A.shape
# Add slack variables
M = np.hstack([A, np.eye(m)])
c_aug = np.concatenate([c, np.zeros(m)])
# Initial BFS: slack variables are basic
basis = list(range(n, n + m))
non_basis = list(range(n))
while True:
# Compute reduced costs
B = M[:, basis]
N = M[:, non_basis]
c_B = c_aug[basis]
c_N = c_aug[non_basis]
y = np.linalg.solve(B.T, c_B)
reduced_costs = c_N - N.T @ y
if np.all(reduced_costs >= -1e-10):
break # Optimal
# Enter: most negative reduced cost
enter_idx = np.argmin(reduced_costs)
enter_var = non_basis[enter_idx]
# Direction vector
d = np.linalg.solve(B, M[:, enter_var])
if np.all(d <= 1e-10):
raise ValueError("LP is unbounded")
# Leave: minimum ratio test
x_B = np.linalg.solve(B, b)
ratios = np.where(d > 1e-10, x_B / d, np.inf)
leave_idx = np.argmin(ratios)
leave_var = basis[leave_idx]
# Update basis
basis[leave_idx] = enter_var
non_basis[enter_idx] = leave_var
x = np.zeros(n + m)
x_B = np.linalg.solve(M[:, basis], b)
for i, v in enumerate(basis):
x[v] = x_B[i]
return x[:n], c_aug @ x
# Example
c = np.array([-1, -2])
A = np.array([[1, 1], [1, -1], [-1, 1]])
b = np.array([4, 2, 2])
x_opt, obj = simplex(c, A, b)
print(f"Optimal: x={x_opt}, obj={-obj}")
Duality in LP
DfDual Problem
Every LP (the primal) has an associated dual LP. The dual provides bounds on the primal optimal value and has deep theoretical significance. For a primal minimization problem, the dual is a maximization problem.
PrimalβDual Pair
Here,
- =Primal objective
- =Dual objective
- =Constraint matrix (primal)
- =Transpose (dual constraints)
- =Dual variables (shadow prices)
ThWeak Duality Theorem
For any feasible primal solution and dual solution : . The dual objective always provides a lower bound on the primal objective (for minimization). Equality holds if and only if both solutions are optimal.
ThStrong Duality Theorem
If the primal has an optimal solution , then the dual has an optimal solution with . The optimal values are equal. This holds when both problems are feasible and bounded.
βΉοΈ Complementary Slackness
At optimality, for each constraint pair:
- If , then the -th primal constraint is tight (equality holds): .
- If (primal slack), then .
- If , then the -th dual constraint is tight: .
- If (dual slack), then .
πProblem: Construct the Dual
Given primal: minimize subject to , , . Write the dual.
π‘Solution
Dual: maximize subject to , , . The dual variables represent shadow prices for the two resource constraints.
Sensitivity Analysis
DfSensitivity Analysis
Sensitivity analysis studies how changes in the LP data (costs , right-hand side , or matrix ) affect the optimal solution. It answers: "How much can a parameter change before the current basis is no longer optimal?"
DfShadow Price
The shadow price (dual variable value) measures the rate of change of the optimal objective per unit increase in : . A shadow price of means increasing by improves the objective by .
DfReduced Cost
The reduced cost of a non-basic variable measures the rate of change of the objective per unit increase of from zero: . A large positive reduced cost means forcing is expensive.
β οΈ Range of Optimality
The current basis remains optimal as long as:
- Each cost coefficient (for non-basic ) stays within its allowable range: .
- Each RHS value stays within its allowable range so that . Outside these ranges, a basis change (pivot) is required.
Shadow Price Interpretation
Here,
- =Optimal objective value
- =Optimal dual variables (shadow prices)
- =Perturbation to RHS vector
Transportation Problem
DfTransportation Problem
The transportation problem is a special LP where goods are shipped from suppliers (with supply ) to destinations (with demand ) at minimum cost. The constraint matrix has a special network structure.
Transportation Formulation
Here,
- =Unit cost from supplier i to destination j
- =Quantity shipped from i to j
- =Supply at supplier i
- =Demand at destination j
βΉοΈ Northwest Corner Rule
A feasible starting solution is found by the northwest corner rule: start at the top-left cell , allocate as much as possible, then move right (if demand unmet) or down (if supply remains). This provides an initial BFS for the transportation simplex method.
ThTransportation Problem Optimality
A feasible solution to the transportation problem is optimal if all dual variables for all cells (where and are the dual variables associated with supply and demand constraints). This is checked via the MODI (Modified Distribution) method.
from scipy.optimize import linprog
import numpy as np
def transportation_problem(costs, supply, demand):
"""Solve transportation problem using LP."""
m, n = costs.shape
# Decision variables: x_{ij} flattened as x[i*n + j]
c = costs.flatten()
# Supply constraints: sum over j for each i
A_eq_supply = np.zeros((m, m * n))
for i in range(m):
A_eq_supply[i, i*n:(i+1)*n] = 1
# Demand constraints: sum over i for each j
A_eq_demand = np.zeros((n, m * n))
for j in range(n):
A_eq_demand[j, j::n] = 1
A_eq = np.vstack([A_eq_supply, A_eq_demand])
b_eq = np.concatenate([supply, demand])
result = linprog(c, A_eq=A_eq, b_eq=b_eq, bounds=[(0, None)] * (m*n), method='highs')
if result.success:
return result.x.reshape(m, n), result.fun
return None, None
costs = np.array([[8, 6, 10, 9], [9, 12, 13, 7], [14, 9, 16, 5]])
supply = np.array([35, 50, 40])
demand = np.array([45, 20, 30, 30])
shipment, total_cost = transportation_problem(costs, supply, demand)
print(f"Optimal shipments:\n{shipment}")
print(f"Total cost: {total_cost}")
Network Flow Problems
DfMinimum Cost Network Flow
The minimum cost network flow problem generalizes the transportation problem to arbitrary directed graphs. Flow is sent along edges with capacity limits and costs, subject to supply/demand at nodes and conservation constraints.
Network Flow Formulation
Here,
- =Flow on edge (i,j)
- =Cost per unit flow on edge (i,j)
- =Capacity of edge (i,j)
- =Supply (+) or demand (-) at node i
DfMaximum Flow Problem
The maximum flow problem finds the maximum total flow from a source to a sink in a directed graph with edge capacities. It is dual to the minimum cut problem.
ThMax-Flow Min-Cut Theorem
The maximum flow from to equals the minimum capacity of an - cut (a partition of vertices into two sets, one containing and one containing ). This is the foundational result of network optimization.
βΉοΈ Applications of Network Flow
- Shortest path (set , others ): find minimum cost route.
- Maximum bipartite matching: model as network flow with unit capacities.
- Project selection: choose profitable projects subject to dependency constraints.
- Image segmentation: min-cut formulations for computer vision.
Integer Linear Programming
DfInteger Linear Program (ILP)
An integer linear program is an LP with the additional restriction that some or all decision variables must take integer values. When all variables are integer, it is called a pure ILP; when only some are integer, it is a mixed-integer LP (MILP).
Integer Linear Program
Here,
- =Integer decision variable for j in index set I
- =Constraint matrix (continuous entries allowed)
- =Index set of integer-constrained variables
β οΈ Complexity
ILP is NP-hard in general (unlike LP which is polynomial). The simplex method cannot be directly applied. Common approaches include:
- Branch and bound: systematically enumerate subproblems with LP relaxations.
- Cutting planes: add valid inequalities to tighten the LP relaxation.
- Branch and cut: combine both strategies (used by modern solvers like Gurobi, CPLEX).
DfLP Relaxation
The LP relaxation of an ILP drops the integrality constraints, yielding a standard LP. The LP relaxation provides a lower bound (for minimization) on the ILP optimal value. The gap between the LP relaxation bound and the best known integer solution is called the integrality gap.
πProblem: Mixed-Integer LP
A company produces two products. Product A requires 2 hours of machine time and 1 hour of labor per unit. Product B requires 1 hour of machine time and 3 hours of labor per unit. Machine time available: 8 hours. Labor available: 9 hours. Profit: A = 4. At most 3 units of A can be produced (integer constraint). Maximize profit.
π‘Solution
Formulate: maximize subject to , , , , . Using branch and bound: LP relaxation gives , profit = . Rounding : , profit = . Check feasibility: , . Optimal: , profit = .
Python Implementation
Using SciPy
from scipy.optimize import linprog
import numpy as np
# Example: Maximize z = 3x + 2y
# Subject to: x + y <= 4, x <= 2, y <= 3, x,y >= 0
c = [-3, -2] # Negate for maximization
A_ub = [[1, 1], [1, 0], [0, 1]]
b_ub = [4, 2, 3]
result = linprog(c, A_ub=A_ub, b_ub=b_ub, method='highs')
print(f"Optimal x: {result.x}")
print(f"Maximum z: {-result.fun}")
# Equality constraints example
# min 5x + 4y, s.t. 6x + 4y = 24, x + 2y = 6, x,y >= 0
c2 = [5, 4]
A_eq = [[6, 4], [1, 2]]
b_eq = [24, 6]
result2 = linprog(c2, A_eq=A_eq, b_eq=b_eq, bounds=[(0, None), (0, None)])
print(f"Optimal: x={result2.x}, cost={result2.fun}")
Using PuLP
from pulp import *
# Define the problem
prob = LpProblem("Production_Planning", LpMaximize)
# Decision variables
x1 = LpVariable("Product_A", lowBound=0, cat='Continuous')
x2 = LpVariable("Product_B", lowBound=0, cat='Continuous')
# Objective function
prob += 3 * x1 + 2 * x2, "Total_Profit"
# Constraints
prob += x1 + x2 <= 4, "Resource_1"
prob += x1 <= 2, "Resource_2"
prob += x2 <= 3, "Resource_3"
# Solve
prob.solve(PULP_CBC_CMD(msg=0))
print(f"Status: {LpStatus[prob.status]}")
print(f"Product A = {x1.varValue}")
print(f"Product B = {x2.varValue}")
print(f"Total Profit = {value(prob.objective)}")
# Mixed-Integer example
prob2 = LpProblem("ILP_Example", LpMaximize)
x = LpVariable("x", lowBound=0, cat='Integer')
y = LpVariable("y", lowBound=0, cat='Continuous')
prob2 += 5 * x + 4 * y
prob2 += 2 * x + y <= 8
prob2 += x + 3 * y <= 9
prob2 += x <= 3
prob2.solve(PULP_CBC_CMD(msg=0))
print(f"ILP: x={x.varValue}, y={y.varValue}, obj={value(prob2.objective)}")
Applications in AI/ML
Resource Allocation
βΉοΈ LP in Machine Learning
Linear programming appears in many ML contexts:
- Feature selection: L1-regularized linear regression (Lasso) is equivalent to an LP.
- Support vector machines: Linear SVMs with separable data reduce to LP.
- Reinforcement learning: Linear programming formulations for MDPs.
- Fairness constraints: Enforcing demographic parity can be formulated as LP.
import numpy as np
from scipy.optimize import linprog
# Lasso regression as LP: min ||y - Xw||_1
# Reformulated: min sum(t_i), s.t. y - Xw <= t, -(y - Xw) <= t
np.random.seed(42)
X = np.random.randn(50, 5)
true_w = np.array([1, 0, 0, 0, 0], dtype=float)
y = X @ true_w + 0.1 * np.random.randn(50)
n, p = X.shape
# Variables: [w (p), t (n)]
c = np.concatenate([np.zeros(p), np.ones(n)])
# Constraints: y - Xw <= t => -Xw - t <= -y
# -(y - Xw) <= t => Xw - t <= y
A_ub = np.vstack([
np.hstack([-X, -np.eye(n)]),
np.hstack([X, -np.eye(n)])
])
b_ub = np.concatenate([-y, y])
result = linprog(c, A_ub=A_ub, b_ub=b_ub, method='highs')
w_lasso = result.x[:p]
print(f"Lasso coefficients: {w_lasso.round(3)}")
Portfolio Optimization
from scipy.optimize import linprog
# Linear risk model: minimize tracking error
# min sum |x_i - w_i| subject to budget and sector constraints
n_assets = 5
target = np.array([0.2, 0.2, 0.2, 0.2, 0.2])
# Variables: [x (n), s_plus (n), s_minus (n)]
c = np.concatenate([np.zeros(n_assets), np.ones(n_assets), np.ones(n_assets)])
# x - target = s+ - s-
# x - s+ + s- = target (equality)
A_eq = np.hstack([
np.eye(n_assets),
-np.eye(n_assets),
np.eye(n_assets)
])
b_eq = target
# Budget: sum(x) = 1
A_budget = np.hstack([np.ones((1, n_assets)), np.zeros((1, 2 * n_assets))])
b_budget = [1.0]
A_eq_full = np.vstack([A_eq, A_budget])
b_eq_full = np.concatenate([b_eq, b_budget])
result = linprog(c, A_eq=A_eq_full, b_eq=b_eq_full,
bounds=[(0, 1)] * n_assets + [(0, None)] * (2 * n_assets),
method='highs')
print(f"Optimal weights: {result.x[:n_assets].round(3)}")
Linear Programming in MDPs
DfLP Formulation of MDPs
A Markov Decision Process can be solved via LP: minimize subject to for all state-action pairs . The dual variables correspond to the stationary distribution.
Common Mistakes
| Mistake | Problem | Solution |
|---|---|---|
| Forgetting to convert max to min | linprog always minimizes | Negate objective: |
| Wrong constraint direction | Feasible region is inverted | Check: means constraints are β€ |
| Ignoring non-negativity | Unbounded below | Always specify bounds=[(0, None)] for |
| Infeasible constraints | No solution exists | Check for contradictory constraints; use dual to diagnose |
| Not scaling variables | Numerical instability | Normalize variables to similar magnitudes |
| Confusing β€ and β₯ in dual | Wrong dual formulation | Primal min with β Dual max with |
| Ignoring integer requirements | Fractional solution accepted | Use cat='Integer' in PuLP or MILP solver |
| Wrong reduced cost sign | Misinterpreting optimality | For min: means optimal; for max: |
| Not handling degeneracy | Cycling in simplex | Use Bland's rule or perturbation |
| Assuming global optimum for ILP | Local optima in branch-and-bound | Use global solvers (Gurobi, CPLEX) with tight bounds |
Interview Questions
π‘ Common Interview Questions
- What is the geometric interpretation of an LP? β An LP optimizes a linear function over a convex polytope. The optimum is at a vertex.
- What is duality and why does it matter? β Every LP has a dual; strong duality says optimal values are equal. The dual provides shadow prices.
- When is the simplex method slow? β Worst-case exponential (Klee-Minty example), but typically polynomial in practice. Interior-point methods are provably polynomial.
- What is the difference between LP and ILP? β ILP is NP-hard; LP is polynomial. ILP allows integer variables; LP requires only continuous.
- How does sensitivity analysis help? β It tells you how the solution changes with parameter variations without re-solving.
- What is complementary slackness? β At optimality, if a dual variable is positive, the corresponding primal constraint is tight, and vice versa.
- When would you use interior-point vs simplex? β Interior-point for large-scale; simplex when you need warm-starts or sensitivity analysis.
- How is LP used in ML? β Lasso regression, SVMs (linear case), MDP solving, fairness constraints, feature selection.
- What is a degenerate LP? β A basic feasible solution where one or more basic variables are zero. Can cause cycling in simplex.
- What is the transportation problem special structure? β The constraint matrix is totally unimodular, guaranteeing integer solutions from LP relaxation.
Practice Problems
πProblem 1: Diet Problem
A dietician must plan meals meeting minimum requirements: 50g protein, 40g carbs, 30g fat. Food A provides 10g protein, 8g carbs, 5g fat per serving at 3. Minimize cost.
π‘Solution
Let = servings of A, = servings of B. Minimize subject to , , , . Solving: (cost = 40+10=5032+20=5220+16=36$ β.
πProblem 2: Manufacturing
A factory produces tables and chairs. Each table requires 2 hours of cutting, 4 hours of assembly, 1 hour of finishing. Each chair requires 3 hours of cutting, 2 hours of assembly, 1 hour of finishing. Available: cutting = 120 hrs, assembly = 160 hrs, finishing = 50 hrs. Profit: table = 50. Maximize profit.
π‘Solution
Maximize subject to , , , . Corner points: , , , , . Maximum = at .
πProblem 3: Dual Interpretation
Given primal: minimize subject to , , . What do the dual variables represent? If and , what does this mean?
π‘Solution
Dual: maximize subject to , , . means the first constraint is binding: increasing its RHS from 12 to 13 would improve the objective by 1.5. means the second constraint is slack β relaxing it doesn't help.
πProblem 4: Network Flow
Find the maximum flow from node 1 to node 4 in a network: (1β2: cap 10), (1β3: cap 8), (2β3: cap 5), (2β4: cap 7), (3β4: cap 10).
π‘Solution
By augmenting path method: Path 1β2β4: flow 7 (capacity bottleneck = 7). Path 1β3β4: flow 8 (capacity bottleneck = 8). Path 1β2β3β4: remaining capacity on 1β2 = 3, 2β3 = 5, 3β4 = 2 (remaining after 8). Flow = 2. Total max flow = 7 + 8 + 2 = 17. Verify min cut: cut {1} vs {2,3,4}: capacity = 10+8 = 18. Cut {1,2} vs {3,4}: 5+7 = 12. Cut {1,3} vs {2,4}: 10+10 = 20. Cut {1,2,3} vs {4}: 7+10 = 17. Min cut = 17 = max flow β.
πProblem 5: Integer Programming
A logistics company must decide which of 5 warehouses to open. Opening warehouse costs . Each warehouse can serve certain regions at cost . Demand in region is . Formulate as MILP.
π‘Solution
Binary variables : 1 if warehouse is open. Flow variables : amount shipped from to . Minimize subject to (demand), (capacity link), , . The big-M constraint ensures flow only from open warehouses.
Quick Reference
πLinear Programming Quick Reference
- Standard Form: s.t. , .
- Dual Form: Primal , β Dual , , .
- Strong Duality: at optimality.
- Complementary Slackness: and .
- Shadow Price: β marginal value of resource .
- Simplex: Moves along vertices; polynomial in practice, exponential worst-case.
- Interior Point: Polynomial ; no vertex information.
- ILP: NP-hard; use branch-and-cut (Gurobi, CPLEX).
- Transportation: Special LP with totally unimodular matrix; LP relaxation gives integer solutions.
- Network Flow: Min-cost flow generalizes transportation; max-flow = min-cut.
- Python:
scipy.optimize.linprog(simplex/highs),pulp(modeling), Gurobi/CPLEX (large-scale).
πComplexity Summary
| Problem | Complexity | Algorithm |
|---|---|---|
| LP (continuous) | Polynomial | Interior point |
| LP (simplex) | Exponential worst, fast practical | Simplex |
| ILP / MILP | NP-hard | Branch-and-cut |
| Transportation | Polynomial (special structure) | Transportation simplex |
| Network flow | Polynomial | Simplex on networks |
| Max flow | Polynomial | Ford-Fulkerson, push-relabel |
Cross-References
βΉοΈ Related Topics
- 065 β Constrained Optimization β Lagrange multipliers, KKT conditions β the continuous analog of duality.
- 067 β Quadratic Programming β Extends LP with quadratic objective; used in SVMs and portfolio optimization.
- 070 β Applications in Deep Learning β How optimization powers neural network training.
- 074 β Graphs β Network structures underlying flow problems.
- 031 β Lagrange Multipliers β Theoretical foundation for LP duality.
- 064 β Newton's Method: Interior-point methods use Newton steps on the barrier problem.
- 068 β Metaheuristic Optimization β Genetic algorithms and simulated annealing for problems where LP doesn't apply.
- 069 β Hyperparameter Optimization β Continuous optimization for tuning ML models.