pyomo icon indicating copy to clipboard operation
pyomo copied to clipboard

SCIP solver termination condition is "other" when gap limit reached

Open adbuerger opened this issue 8 months ago • 1 comments

Summary

I solved the same sample integer program with different solvers (CBC, SCIP, HiGHS) until a defined gap limit was reached (but not to full optimality). I noticed that CBC and HiGHS solver stated "optimal" as termination condition, while SCIP stated "other". This appears inconsistent to me and I assume that (since I think a termination condition "gap limit reached" does not exist in Pyomo?) SCIP should also return "optimal" in that case.

Thank you for your consideration.

Steps to reproduce the issue

You can see the behavior when running the following example:

import pyomo.environ as pyo
import random

random.seed(100)
MIP_GAP = 1.0
TEE = False

MIP_GAP_KEYWORD = {
    "cbc": "ratioGap",
    "appsi_highs": "mip_rel_gap",
    "scip": "limits/gap",
}

for solver_name in ["cbc", "appsi_highs", "scip"]:
    m = pyo.ConcreteModel()
    m.x = pyo.Var(range(101), domain=pyo.Binary)
    m.o = pyo.Objective(expr=sum(m.x[j] for j in m.x), sense=pyo.minimize)
    m.c = pyo.ConstraintList()
    for _ in range(200):
        m.c.add(sum(random.choice([0, 1]) * m.x[j] for j in m.x) >= 1)
    m.c.add(sum(m.x[j] for j in m.x) <= 30)

    solver = pyo.SolverFactory(solver_name)
    solver.options[MIP_GAP_KEYWORD[solver_name]] = MIP_GAP

    results = solver.solve(m, tee=TEE)

    print(solver_name, ":", results.solver.termination_condition)

The above code returns:

cbc : optimal
appsi_highs : optimal
scip : other

Information on your system

Pyomo version: 6.9.1 Python version: 3.11.2 Operating system: Debian 12 How Pyomo was installed (PyPI, conda, source): PyPI Solver (if applicable): CBC, HiGHS, SCIP

Additional information

I think the termination condition is set here: https://github.com/Pyomo/pyomo/blob/457f436bf7aecfde8f57b7f88b62ca800bdd0264/pyomo/solvers/plugins/solvers/SCIPAMPL.py#L342

adbuerger avatar May 08 '25 12:05 adbuerger

Coincidentally, this came up in SCIP.jl last week: https://github.com/scipopt/SCIP.jl/issues/304#issuecomment-2846311778

We map SCIP_STATUS_GAPLIMIT to MOI.OPTIMAL (code).

The SCIP log for this status is

SCIP Status        : solving was interrupted [gap limit reached]

which will probably confuse users regardless of which convention you choose.

odow avatar May 08 '25 21:05 odow