Linear Programs
A linear program (LP) is a special case of the ConicIP problem formulation with Q = 0:
minimize -cᵀy
subject to Ay ≥ b
Gy = dExample: LP with Equality and Inequality Constraints
Solve a small LP with nonnegativity and an equality constraint:
minimize -2y₁ - 3y₂ - y₃ - y₄ - y₅
subject to y₁ + y₂ + y₃ + y₄ + y₅ = 4
y ≥ 0using ConicIP, SparseArrays, LinearAlgebra
n = 5
Q = spzeros(n, n)
c = [2.0, 3.0, 1.0, 1.0, 1.0]
# Nonnegativity: y ≥ 0
A = sparse(1.0I, n, n)
b = zeros(n)
cone_dims = [("R", n)]
# Equality constraint: sum(y) = 4
G = ones(1, n)
d = [4.0]
sol = conicIP(Q, c, A, b, cone_dims, G, d; verbose=false)
sol.status:Optimalround.(sol.y, digits=4)5-element Vector{Float64}:
0.0
4.0
0.0
0.0
0.0The optimal solution puts all weight on the variable with the largest objective coefficient (y₂ = 4).
Reading Dual Variables
The dual variables sol.v give the shadow prices for the inequality constraints. Each component of v corresponds to one row of A y ≥ b.
round.(sol.v, digits=4)5-element Vector{Float64}:
1.0
0.0
2.0
2.0
2.0The dual variable for the equality constraint is in sol.w:
round.(sol.w, digits=4)1-element Vector{Float64}:
3.0Verifying Optimality
At optimality, the primal and dual objectives should match:
(pobj=round(sol.pobj, digits=6), dobj=round(sol.dobj, digits=6))(pobj = -11.999999, dobj = -12.0)And all feasibility residuals should be small:
(prFeas=sol.prFeas, duFeas=sol.duFeas, muFeas=sol.muFeas)(prFeas = 4.440892126870336e-16, duFeas = 1.9190313209659643e-7, muFeas = 5.186112314201071e-8)A Larger Example: Transportation Problem
Consider a transportation problem with 3 supply nodes and 4 demand nodes. The cost of shipping one unit from supply node i to demand node j is cost[i,j]. We want to minimize total shipping cost subject to supply and demand constraints.
using Random
Random.seed!(123)
nsupply, ndemand = 3, 4
cost = rand(nsupply, ndemand) .+ 0.1
# Decision variables: x[i,j] = amount shipped from i to j
nvar = nsupply * ndemand
Q = spzeros(nvar, nvar)
c = vec(cost) # minimize (note: conicIP minimizes -c'y, so negate)
c = -c # we want to minimize cost'y, so set c = -cost
# Nonnegativity
A = sparse(1.0I, nvar, nvar)
b_ineq = zeros(nvar)
cone_dims = [("R", nvar)]
# Supply constraints: sum_j x[i,j] = supply[i]
# Demand constraints: sum_i x[i,j] = demand[j]
supply = [10.0, 15.0, 20.0]
demand = [8.0, 12.0, 10.0, 15.0] # sum(demand) = sum(supply) = 45
G_supply = zeros(nsupply, nvar)
for i in 1:nsupply
for j in 1:ndemand
G_supply[i, (i-1)*ndemand + j] = 1.0
end
end
G_demand = zeros(ndemand, nvar)
for j in 1:ndemand
for i in 1:nsupply
G_demand[j, (i-1)*ndemand + j] = 1.0
end
end
G = [G_supply; G_demand]
d = [supply; demand]
sol2 = conicIP(Q, c, A, b_ineq, cone_dims, G, d; verbose=false)
sol2.status:AbandonedThe optimal shipping plan:
shipments = reshape(round.(sol2.y, digits=2), nsupply, ndemand)3×4 Matrix{Float64}:
0.0 10.0 0.0 9.95
0.0 8.0 4.95 10.0
0.0 2.05 0.0 0.05