LP Warm Starts - using Gurobi with JuMP

The key is in the Gurobi documentation for PStart, DStart, et cetera:

Note that any model modifications which are pending or are made after setting PStart (adding variables or constraints, changing coefficients, etc.) will discard the start. You should only set this attribute after you are done modifying your model.

Check the following minimal working example (note the use of direct_model and the corresponding update). For the primal simplex (Method = 0), it appears sufficient to specify the PStart; conversely, for the dual simplex (Method = 1), it appears sufficient to specify just the DStart). If these values are not specified in the corresponding cases the solver outputs LP warm-start: discard starts.

using JuMP
using Gurobi

model = direct_model(Gurobi.Optimizer())

@variable(model, x[1:2] >= 0)
@objective(model, Max, 2*x[1] + x[2])
@constraint(model, c1, x[1] <= 1)
@constraint(model, c3, x[2] <= 1)
set_optimizer_attribute(model, "Method", 0) # Primal Simplex
set_optimizer_attribute(model, "Presolve", 0)

grb = backend(model)
@show(grb.needs_update) # This yields true
Gurobi.GRBupdatemodel(grb) # Thus, we need to do this

MOI.set(model, Gurobi.VariableAttribute("PStart"), x[1], 0.75)
MOI.set(model, Gurobi.VariableAttribute("PStart"), x[2], 0.75)
#MOI.set(model, Gurobi.ConstraintAttribute("DStart"), c1, 2.0)
#MOI.set(model, Gurobi.ConstraintAttribute("DStart"), c3, 1.0)

optimize!(model)

Output (using Gurobi 9.5):

Optimize a model with 2 rows, 2 columns and 2 nonzeros
Coefficient statistics:
  Matrix range     [1e+00, 1e+00]
  Objective range  [1e+00, 2e+00]
  Bounds range     [0e+00, 0e+00]
  RHS range        [1e+00, 1e+00]
Primal warm-start: 2 superbasic variables.
Iteration    Objective       Primal Inf.    Dual Inf.      Time
       0    2.2500000e+00   0.000000e+00   3.000000e+00      0s
       2    3.0000000e+00   0.000000e+00   0.000000e+00      0s

Solved in 2 iterations and 0.00 seconds (0.00 work units)
Optimal objective  3.000000000e+00
1 Like