Hello,
I have a large LP model that I want to iteratively solve over changing parameters. Up until now, using set_normalized_rhs
and set_normalized_coefficient
works very well when HiGHS is an optimizer. However, when I switch to Gurobi, it worryingly takes longer time to modify a model, >3 min. vs a few seconds.
I tried to improve this by using direct_model()
instead of Model()
to create the model. This leads to only a slight improvement.
Have I implemented something wrong?
Since I would like to use Gurobi due to its performance and I would prefer not to recreate a model every time, which is still faster than to modify existing models, is there anything I can try?
Ps. it is my first time in the forum, and thank you in advance for any suggestion
The following is an MWE with a dummy LP problem.
using JuMP, Gurobi, HiGHS, BenchmarkTools
ENV["GUROBI_HOME"] = "C:\\gurobi1003\\win64"
Gurobi_solver = optimizer_with_attributes(Gurobi.Optimizer)
HiGHS_solver = optimizer_with_attributes(HiGHS.Optimizer)
# Functions to initialize and modify an LP model
function initialize_indirect(; nvar=1000, ncon=1000)
m = Model()
@variable(m, 0 ā¤ x[1:nvar])
@constraint(m, ec, rand(ncon, nvar) * x .== rand(ncon))
@constraint(m, ic, rand(ncon, nvar) * x .ā„ rand(ncon))
@objective(m, Min, sum(randn(nvar) .* x))
return m
end
function initialize_direct(solver; nvar=1000, ncon=1000)
m = direct_model(solver)
@variable(m, 0 ā¤ x[1:nvar])
@constraint(m, ec, rand(ncon, nvar) * x .== rand(ncon))
@constraint(m, ic, rand(ncon, nvar) * x .ā„ rand(ncon))
@objective(m, Min, sum(randn(nvar) .* x))
return m
end
function modify!(m, ncon=1000)
set_normalized_rhs.(m[:ec], rand(ncon))
set_normalized_coefficient.(m[:ec], m[:x][1], rand(ncon))
set_normalized_coefficient.(m[:ec], m[:x][2], rand(ncon))
set_normalized_coefficient.(m[:ic], m[:x][3], rand(ncon))
set_normalized_coefficient.(m[:ic], m[:x][4], rand(ncon))
return nothing
end
# Test with Gurobi
m = initialize_indirect()
set_optimizer(m, Gurobi_solver)
optimize!(m)
@btime modify!(m)
### 24.115 ms (15028 allocations: 337.36 KiB)
m = initialize_direct(Gurobi_solver)
optimize!(m)
@btime modify!(m)
### 15.098 ms (10028 allocations: 259.23 KiB)
# Test with HiGHS
m = initialize_indirect()
set_optimizer(m, HiGHS_solver)
optimize!(m)
@btime modify!(m)
### 8.422 ms (15028 allocations: 337.36 KiB)
m = initialize_direct(HiGHS_solver)
optimize!(m)
@btime modify!(m)
### 2.851 ms (10028 allocations: 259.23 KiB)