Description
Here's code for a small working example. The problem is a network flow problem over a complete graph: n
points are generated in the unit square, corresponding to vertices of the graph. Vectors x
and y
of length n
and sum 1
correspond to vertex-wise supply and demand. Script:
using JuMP, GLPK, Gurobi, Random
# build a network flow JuMP model
# n (dense) constraints, n^2 variables
function build_jumpmodel(x, y, dm, optimizer)
n = length(x)
@assert n == length(y)
m = JuMP.Model(with_optimizer(optimizer))
@variable(m, f[1:n, 1:n] >= 0)
@objective(m, Min, sum(dm[i,j] * f[i,j] for i in 1:n, j in 1:n))
# correct net change at each voxel to transform x to y
for i in 1:n
@constraint(m,
sum(f[j,i] for j in 1:n)
- sum(f[i,j] for j in 1:n)
== y[i] - x[i]
)
end
return m
end
function random_network_flow(n, optimizer)
Random.seed!(123)
# n random vertices in the unit square
# random weight vectors, each summing to 1
vert_locs = rand(2,n)
dm = zeros(n,n)
for i in 1:n, j in 1:n
dm[i,j] = (vert_locs[:,i] - vert_locs[:,j]).^2 |> sum |> sqrt
end
x = rand(n); x ./= sum(x)
y = rand(n); y ./= sum(y)
build_time = @elapsed m = build_jumpmodel(x, y, dm, optimizer)
@show build_time
solve_time = @elapsed JuMP.optimize!(m)
println()
@show solve_time
return JuMP.objective_value(m)
end
Example output:
julia> @profile random_network_flow(150, Gurobi.Optimizer)
Academic license - for non-commercial use only
build_time = 0.288749231
Warning: excessive time spent in model updates.
Consider calling update less frequently.
Optimize a model with 150 rows, 22500 columns and 44700 nonzeros
Coefficient statistics:
Matrix range [1e+00, 1e+00]
Objective range [8e-03, 1e+00]
Bounds range [0e+00, 0e+00]
RHS range [4e-05, 1e-02]
Concurrent LP optimizer: primal simplex, dual simplex, and barrier
Showing barrier log only...
Presolve removed 1 rows and 150 columns
Presolve time: 0.02s
Presolved: 149 rows, 22350 columns, 44402 nonzeros
Ordering time: 0.00s
Barrier statistics:
AA' NZ : 1.103e+04
Factor NZ : 1.118e+04 (roughly 9 MBytes of memory)
Factor Ops : 1.114e+06 (less than 1 second per iteration)
Threads : 4
Barrier performed 0 iterations in 0.04 seconds
Barrier solve interrupted - model solved by another algorithm
Solved with primal simplex
Solved in 1445 iterations and 0.04 seconds
Optimal objective 3.122653030e-02
solve_time = 2.96464323
0.031226530301749666
# for context, using GLPK
julia> random_network_flow(150, GLPK.Optimizer)
build_time = 0.112245802
solve_time = 0.216538412
0.031226530301749662
Notice that the overall solve time with Gurobi is order of magnitude worse than with GLPK, but of the ~3 seconds needed for JuMP.optimize!
with Gurobi, only ~.04 seconds are spent in Gurobi! Gurobi also warns that excessive time is spent in model updates.
Basic profiling seems a little unreliable here, or I am bad at reading it - reported line numbers and functions don't always agree. That said, looks like lots of time is spent in update_model!
of grb_model.jl
.
Edit: forgot to mention - this is with Gurobi.jl v0.5.8, LQOI v0.6.0, Gurobi the solver 8.1.