Is there a way to control/prevent how a LP solver may use information from a previous solve to warm start? I know, e.g., for Gurobi there is LPWarmStart, but I struggle to prevent that for example when using HiGHS.
What happens?
See the MWE at the end. I’d like to use some kind of force_fresh_solve parameter, but could not find anything (even though I vaguely remembered to have seen something similar some time ago…).
Background
Maybe also important why I’m stuck at this: I’m repeatedly solving a model while switching around some settings based on an (un)educated guess of what I expect to be working better for the next solve. Unfortunately, the previous solve prevents a presolve, which hurts more than the warm start helps.
Thanks!
Code for MWE
The following constructs a model, solves it, changes the objective, and re-solves. Not having a previous solution - can be tested by not executing “line 42” - requires 241 simplex iterations, compared to 410 when optimize! was called before.
Note: Happens for dual simplex, or other settings that are changed too.
using JuMP
import HiGHS
import Random: seed!
# Random data.
seed!(12345)
N, M = (500, 500)
A = abs.(randn(N, M))
b = randn(N)
c = abs.(randn(M)), abs.(randn(M))
r = randn(M) .* 100
# Model setup.
m = Model(HiGHS.Optimizer)
set_attribute(m, "simplex_strategy", 4)
@variable(m, r[i] <= x[i = 1:M] <= (r .+ 100)[i])
@constraint(m, A * x .>= b)
@objective(m, Min, c[1]' * x)
# Solve 1.
optimize!(m) # := line 42
# Modify.
@objective(m, Min, c[2]' * x)
# Solve 2.
optimize!(m)
As a high level comment, I get the sense that you are trying too hard to tune the solvers. Worrying about whether it takes 241 or 410 simplex iterations can make a difference for HiGHS and your current test set, but you might find that your parameters etc are suboptimal if you update HiGHS, or if you use some new data in a couple of months. In most cases, letting HiGHS decide to warmstart is probably a good thing.
With that said, the MWE was probably chosen too simple (but it was the only one I could quickly draft). One example for a setting that is a “no-brainer” (ok… under specific circumstances), is presolve: off.
It’s really hard convincing HiGHS to turn presolve on again, for example:
solve (ret: infeasible)
presolve: off
resolve => dualray
ensure feasibility
presolve: on
turn on presolve
try resolve.
Having presolve skipped (even though it’s set to on) - based on an infeasible previous run - may (worst case) prevent HiGHS from finding a solution to the now feasible model.
Buuut… yeah, the actual “performance” code makes use of direct_model. I’ll just refactor to using non direct mode for HiGHS for now, and see if that helps. Maybe I don’t need direct mode at all afterwards.
I’m encountering similar issue.
I find that the default setting of Gurobi isn’t satisfying.
The second solve is problematic (e.g. Warning, Markowitz…), after an obj coeff change from the initial solve.
If we solve the second-solve problem from scratch, it is all right.
Therefore I’m also seeking tuning the solver.
Maybe set_attribute(model, "LPWarmStart", 0), I’ll do some tests and then judge.