Skip to content

highs: wrong optimization result with presolve since highs v1.14.0 #648

Description

@maurerle

Version Checks (indicate both or one)

  • I have confirmed this bug exists on the lastest release of Linopy.

  • I have confirmed this bug exists on the current master branch of Linopy.

Issue Description

optimizing:

minimize 2x + y
s. t. 2*x0 + y0 >= 10
with x binary
and 9 <= y

should result in y=10 and x=0 but results (as with HiGHS 1.11) - but gives the wrong result with HiGHS 1.14 and linopy.

Besides downgrading, it helps to disable presolve (m.solve(solver_name='highs', presolve= "off")).

Running HiGHS 1.14.0 (git hash: 7df0786): Copyright (c) 2026 under MIT licence terms
MIP linopy-problem-hu0mxzpo has 1 row; 2 cols; 2 nonzeros; 1 integer variables (1 binary)
Coefficient ranges:
Matrix [1e+00, 2e+00]
Cost [1e+00, 2e+00]
Bound [1e+00, 9e+00]
RHS [1e+01, 1e+01]
Presolving model
1 rows, 1 cols, 1 nonzeros 0s
0 rows, 0 cols, 0 nonzeros 0s
Presolve reductions: rows 0(-1); columns 0(-2); nonzeros 0(-2) - Reduced to empty
Presolve: Optimal
Src: B => Branching; C => Central rounding; F => Feasibility pump; H => Heuristic;
I => Shifting; J => Feasibility jump; L => Sub-MIP; P => Empty MIP; R => Randomized rounding;
S => Solve LP; T => Evaluate node; U => Unbounded; X => User solution; Y => HiGHS solution;
Z => ZI Round; l => Trivial lower; p => Trivial point; u => Trivial upper; z => Trivial zero
Nodes | B&B Tree | Objective Bounds | Dynamic Constraints | Work Src Proc. InQueue | Leaves Expl. | BestBound BestSol Gap | Cuts InLp Confl. | LpIters Time
0 0 0 0.00% 11 11 0.00% 0 0 0 0 0.0s
Solving report
Model linopy-problem-hu0mxzpo
Status Optimal
Primal bound 11
Dual bound 11
Gap 0% (tolerance: 0.01%)
P-D integral 0
Solution status feasible
11 (objective)
0 (bound viol.)
0 (int. viol.)
0 (row viol.)
Timing 0.00
Max sub-MIP depth 0
Nodes 0
Repair LPs 0
LP iterations 0
Status: ok
Objective: 11.0
x0: 1.0
y0: 9.0

Reproducible Example

importlinopy# 1. Initialize the modelm=linopy.Model()
# 2. Define Variables# x0 is binary, y0 has a lower bound of 9x0=m.add_variables(binary=True, name='x0')
y0=m.add_variables(lower=9, name='y0')
# 3. Add Constraintsm.add_constraints(2*x0+y0>=10, name='c0')
# 4. Set Objective (Minimize 2*x0 + y0)m.add_objective(2*x0+y0)
# 5. Solve using HiGHSm.solve(solver_name='highs')
# 6. Display Resultsprint(f"Status: {m.status}")
print(f"Objective: {m.objective.value}")
print(f"x0: {x0.solution.item()}")
print(f"y0: {y0.solution.item()}")

Expected Behavior

Running HiGHS 1.11.0 (git hash: 364c83a): Copyright (c) 2025 HiGHS under MIT licence terms
MIP linopy-problem-5rmiip7y has 1 rows; 2 cols; 2 nonzeros; 1 integer variables (1 binary)
Coefficient ranges:
Matrix [1e+00, 2e+00]
Cost [1e+00, 2e+00]
Bound [1e+00, 9e+00]
RHS [1e+01, 1e+01]
Presolving model
0 rows, 1 cols, 0 nonzeros 0s
0 rows, 0 cols, 0 nonzeros 0s
Presolve: Optimal
Src: B => Branching; C => Central rounding; F => Feasibility pump; J => Feasibility jump;
H => Heuristic; L => Sub-MIP; P => Empty MIP; R => Randomized rounding; Z => ZI Round;
I => Shifting; S => Solve LP; T => Evaluate node; U => Unbounded; X => User solution;
z => Trivial zero; l => Trivial lower; u => Trivial upper; p => Trivial point
Nodes | B&B Tree | Objective Bounds | Dynamic Constraints | Work Src Proc. InQueue | Leaves Expl. | BestBound BestSol Gap | Cuts InLp Confl. | LpIters Time
0 0 0 0.00% 10 10 0.00% 0 0 0 0 0.0s
Solving report
Model linopy-problem-5rmiip7y
Status Optimal
...
Status: ok
Objective: 10.0
x0: 0.0
y0: 10.0

Installed Versions

Details Replace this line.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions