Skip to content

Solution hint is not passed to the HiGHS solver using mathopt #4345

@pavlomuts

Description

@pavlomuts

What version of OR-Tools and what language are you using?
Version: 9.10
Language: Python

Which solver are you using (e.g. CP-SAT, Routing Solver, GLOP, BOP, Gurobi)
HiGHS, SCIP

What operating system (Linux, Windows, ...) and version?
Ubuntu 22.04

What did you do?
Using the following simple model I am trying to pass to the solver a solution hint in order to warm start it.

from ortools.math_opt.python import mathopt, model_parameters

model = mathopt.Model()
x = model.add_integer_variable(name="x")
y = model.add_integer_variable(name="y")

model.add_linear_constraint(2 * x + 2 * y >= 7)
model.add_linear_constraint(3 * x + 4 * y >= 12)
model.add_linear_constraint(2 * x + y >= 6)

model.minimize_linear_objective(8 * x + 10 * y)

params = mathopt.SolveParameters()
params.enable_output = True

solution_hint = model_parameters.SolutionHint(variable_values={x: 1, y: 25})
mathopt.solve(
    model,
    mathopt.SolverType.HIGHS,
    params=params,
    model_params=model_parameters.ModelSolveParameters(solution_hints=[solution_hint]),
)

The output below clearly indicates that the solution hint was not taken into account, as first BestSol is inf:

Coefficient ranges:
  Matrix [1e+00, 4e+00]
  Cost   [8e+00, 1e+01]
  Bound  [0e+00, 0e+00]
  RHS    [6e+00, 1e+01]
Presolving model
3 rows, 2 cols, 6 nonzeros  0s
3 rows, 2 cols, 6 nonzeros  0s
Objective function is integral with scale 0.5

Solving MIP model with:
   3 rows
   2 cols (0 binary, 2 integer, 0 implied int., 0 continuous)
   6 nonzeros

        Nodes      |    B&B Tree     |            Objective Bounds              |  Dynamic Constraints |       Work      
     Proc. InQueue |  Leaves   Expl. | BestBound       BestSol              Gap |   Cuts   InLp Confl. | LpIters     Time

         0       0         0   0.00%   -inf            inf                  inf        0      0      0         0     0.0s
 T       0       0         0   0.00%   -inf            32                 Large        0      0      0         3     0.0s

Solving report
  Status            Optimal
  Primal bound      32
  Dual bound        32
  Gap               0% (tolerance: 0.01%)
  Solution status   feasible
                    32 (objective)
                    0 (bound viol.)
                    1.7763568394e-15 (int. viol.)
                    0 (row viol.)
  Timing            0.00 (total)
                    0.00 (presolve)
                    0.00 (postsolve)
  Nodes             1
  LP iterations     3 (total)
                    0 (strong br.)
                    0 (separation)
                    0 (heuristics)

The same model but solved with SCIP shows that solution hint was passed to the solver. The output for SCIP is below:

1/1 feasible solution given by solution candidate storage, new primal bound 2.580000e+02

presolving:
(round 1, fast)       0 del vars, 0 del conss, 0 add conss, 0 chg bounds, 1 chg sides, 0 chg coeffs, 0 upgd conss, 0 impls, 0 clqs
(round 2, exhaustive) 0 del vars, 0 del conss, 0 add conss, 0 chg bounds, 1 chg sides, 0 chg coeffs, 3 upgd conss, 0 impls, 0 clqs
   Deactivated symmetry handling methods, since SCIP was built without symmetry detector (SYM=none).
   Deactivated symmetry handling methods, since SCIP was built without symmetry detector (SYM=none).
presolving (3 rounds: 3 fast, 2 medium, 2 exhaustive):
 0 deleted vars, 0 deleted constraints, 0 added constraints, 0 tightened bounds, 0 added holes, 1 changed sides, 0 changed coefficients
 0 implications, 0 cliques
presolved problem has 2 variables (0 bin, 2 int, 0 impl, 0 cont) and 3 constraints
      3 constraints of type <varbound>
transformed objective value is always integral (scale: 2)
Presolving Time: 0.00
transformed 2/2 original solutions to the transformed problem space

 time | node  | left  |LP iter|LP it/n|mem/heur|mdpt |vars |cons |rows |cuts |sepa|confs|strbr|  dualbound   | primalbound  |  gap   | compl. 
i 0.0s|     1 |     0 |     0 |     - |  oneopt|   0 |   2 |   3 |   3 |   0 |  0 |   0 |   0 |      --      | 4.800000e+01 |    Inf | unknown
* 0.0s|     1 |     0 |     2 |     - |    LP  |   0 |   2 |   3 |   3 |   0 |  0 |   0 |   0 | 3.200000e+01 | 3.200000e+01 |   0.00%| unknown
  0.0s|     1 |     0 |     2 |     - |   590k |   0 |   2 |   3 |   3 |   0 |  0 |   0 |   0 | 3.200000e+01 | 3.200000e+01 |   0.00%| unknown

SCIP Status        : problem is solved [optimal solution found]
Solving Time (sec) : 0.01
Solving Nodes      : 1
Primal Bound       : +3.20000000000000e+01 (4 solutions)
Dual Bound         : +3.20000000000000e+01
Gap                : 0.00 %

What did you expect to see
The solution is passed to the HiGHS solver by mathopt interface. HiGHS indeed accepts the solution hint, checked using highspy. The mode using highspy:

from highspy import Highs, HighsSolution, HighsVarType

h = Highs()

x = h.addVariable(obj=8, name="x", type=HighsVarType.kInteger)
y = h.addVariable(obj=10, name="y", type=HighsVarType.kInteger)

h.addConstr(2 * x + 2 * y >= 7)
h.addConstr(3 * x + 4 * y >= 12)
h.addConstr(2 * x + y >= 6)

h.setMinimize()


sol = HighsSolution()
sol.col_value = [1, 25]
h.setSolution(sol)

h.solve()

And the output:

Running HiGHS 1.7.2 (git hash: 184e327): Copyright (c) 2024 HiGHS under MIT licence terms
Coefficient ranges:
  Matrix [1e+00, 4e+00]
  Cost   [8e+00, 1e+01]
  Bound  [0e+00, 0e+00]
  RHS    [6e+00, 1e+01]
Assessing feasibility of MIP using primal feasibility and integrality tolerance of       1e-06
Solution has               num          max          sum
Col     infeasibilities      0            0            0
Integer infeasibilities      0            0            0
Row     infeasibilities      0            0            0
Row     residuals            0            0            0
Presolving model
3 rows, 2 cols, 6 nonzeros  0s
3 rows, 2 cols, 6 nonzeros  0s

MIP start solution is feasible, objective value is 258
Objective function is integral with scale 0.5

Solving MIP model with:
   3 rows
   2 cols (0 binary, 2 integer, 0 implied int., 0 continuous)
   6 nonzeros

        Nodes      |    B&B Tree     |            Objective Bounds              |  Dynamic Constraints |       Work      
     Proc. InQueue |  Leaves   Expl. | BestBound       BestSol              Gap |   Cuts   InLp Confl. | LpIters     Time

         0       0         0   0.00%   0               258              100.00%        0      0      0         0     0.0s
 T       0       0         0   0.00%   0               32               100.00%        0      0      0         3     0.0s

Solving report
  Status            Optimal
  Primal bound      32
  Dual bound        32
  Gap               0% (tolerance: 0.01%)
  Solution status   feasible
                    32 (objective)
                    0 (bound viol.)
                    1.7763568394e-15 (int. viol.)
                    0 (row viol.)
  Timing            0.01 (total)
                    0.00 (presolve)
                    0.00 (postsolve)
  Nodes             1
  LP iterations     3 (total)
                    0 (strong br.)
                    0 (separation)
                    0 (heuristics)

What did you see instead?
The solution hint was not passed HiGHS using mathopt interface.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions