Skip to content

Contrib HiGHS: support partial MIP warm starts - #4047

Open
adbuerger wants to merge 2 commits into
Pyomo:mainfrom
adbuerger:contrib-solver-highs-warmstart
Open

adbuerger wants to merge 2 commits into
Pyomo:mainfrom
adbuerger:contrib-solver-highs-warmstart

Conversation

@adbuerger

Copy link
Copy Markdown

Fixes

Part 2 of #4044 (part 1: #4046)

Summary/Motivation:

The contrib.solver HiGHS interface (highs) has no MIP warm start. The Gurobi and SCIP interfaces in the same framework provide the warmstart_discrete_vars option, which passes the current values of the integer variables to the solver. This PR adds the same option for HiGHS. Because only discrete values are passed, the start is partial by design. HiGHS supports partial starts since 1.8 through the sparse setSolution(num_entries, index, value) overload: all columns not passed are set to kHighsUndefined, and HiGHS completes the start itself.

Changes proposed in this PR:

  • Add HighsConfig (derived from PersistentBranchAndBoundConfig) with the option warmstart_discrete_vars (default False), worded as in the Gurobi and SCIP interfaces.

  • Add Highs._mipstart(), which passes all integer variables that have a value to HiGHS via the sparse setSolution overload. On HiGHS < 1.8, which has neither the overload nor partial starts, it logs a warning and skips the start. It is called before capture_output, because a warning logged inside that block would only end up in the solver log.

  • Add tests to test_highs.py:

    • a full start, whose reported objective value also shows that continuous values are not passed;
    • a partial start;
    • two re-solves on the same persistent instance: the start uses the current values (including the loaded results of the previous solve), and a value reset to None is not carried over from the previous start;
    • the warning on HiGHS < 1.8, using a subclass that reports version 1.7.0 (no mock).

    The warm-start tests are skipped on HiGHS < 1.8.

AI-Use Disclosure

  • AI tools were NOT used during the preparation of this PR

or

  • AI tools contributed to the development of this PR

    • AI tools generated documentation (including the PR description/comments, code comments, and/or Sphinx documentation)
    • AI tools generated tests (baselines, examples, and/or code)
    • AI tools generated code (apart from tests)

    Review process (select ONE):

    • Rewritten: All AI-generated content was rewritten by me before being committed.
    • Reviewed/verified: I retained AI-generated content and verified it before committing. Verification included (as applicable):
      • Ran the code and fixed issues
      • Added and ran tests
      • Checked correctness/logic of code and tests
      • Checked for alignment with the contribution guide
      • Considered security implications
    • As-is: AI-generated content was commited directly to the repository

Notes for reviewers (optional):

Behaviour on re-solves: every solve passes the values the variables have at that time, so after a solve the loaded results serve as the next start. Variables without a value are left undefined, because a new sparse solution is passed on every solve. With the option off, nothing is passed, although HiGHS itself may reuse its last solution if the model has not changed (existing HiGHS behaviour, not touched here).

One question:

  • Gurobi's _mipstart() only sets Start for variables that have a value. In the persistent interface, a variable reset to None would therefore probably (I did not verify it yet) keep its Start from an earlier solve. Is that intended?

The partial-start test uses the same deliberately loose constraint as in #4046 (x1 <= 3 + 7 * x3); with a tighter version, presolve solves the model before the start is evaluated. The sparse setSolution overload is available from HiGHS 1.8 on; I tested with highspy 1.15.1.

Legal Acknowledgement

By contributing to this software project, I have read the contribution guide and agree to the following terms and conditions for my contribution:

  1. I agree my contributions are submitted under the BSD license.
  2. I represent I am authorized to make the contributions and grant the license. If my employer has rights to intellectual property that includes these contributions, I represent that I have received permission to make contributions and grant the required license on behalf of that employer.

Pass the current values of the discrete variables to HiGHS as a sparse
(partial) MIP start. Requires HiGHS >= 1.8; older versions log a warning
and skip the start.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant