Skip to content

Add WithMipStart trait and Gurobi MIP start support - #13

Merged
lovasoa merged 3 commits into
rust-or:masterfrom
gabriel-gehrke:dev
Jan 9, 2026
Merged

lovasoa merged 3 commits into
rust-or:masterfrom
gabriel-gehrke:dev

Conversation

@gabriel-gehrke

@gabriel-gehrke gabriel-gehrke commented Jan 9, 2026 •

Copy link
Copy Markdown
Contributor

This PR adds support for providing a MIP start (partial initial solution) to solvers that can consume one, and wires it into the Gurobi CLI backend by generating a temporary .mst file and passing it to gurobi_cl via InputFile=....

Motivation

Warm-starting MILPs can significantly reduce solve time when a good incumbent or partial assignment is known (e.g., from a previous solve or a heuristic algorithm). This is also requested downstream at the good_lp package (rust-or/good_lp#111).

Changes

  • Introduce a new trait WithMipStart<T>
  • Implement WithMipStart<GurobiSolver>
    • Writes assignments to a temporary .mst file in Gurobi MIP start format
    • Configures GurobiSolver to pass it through gurobi_cl using InputFile=
  • Add tests
    • Verify arguments() contains an InputFile=/tmp/*.mst entry (without relying on an exact filename)

Example Usage

use lp_solvers::solvers::{GurobiSolver, WithMipStart};

let solver = GurobiSolver::new()
    .with_mip_start([("x", 1.0_f32), ("y", 0.0_f32)])
    .expect("valid MIP start");

Notes

  • The .mst file is persisted in the system temp directory (similar to how “temporary” solution output paths are handled in the crate right now).
  • Follow-up improvements could include
    • cleanup strategy for persisted temp files
    • supporting multiple InputFile= entries, as Gurobi indicates it can do, (e.g., hints .hnt, basis .bas)

@lovasoa
lovasoa requested a review from mfuhr January 9, 2026 13:49
@lovasoa

lovasoa commented Jan 9, 2026

Copy link
Copy Markdown
Contributor

Happy to merge once ci passes

@gabriel-gehrke

Copy link
Copy Markdown
Contributor Author

Ah, I hardcoded /tmp in the test instead of handling it via the environment. I'm on it.

In the meantime, what do you think about switching from a hash map to an iterator based start solution as in good_lp's WithInitialSolution? In the beginning I thought this was overkill (and the hash map way fitting in better with the existing codebase) but now I think especially for large problems the conversion to hash map and back when calling from good_lp is unnecessary.

@lovasoa

lovasoa commented Jan 9, 2026

Copy link
Copy Markdown
Contributor

I doubt there are any cases when the performance impact won't be tiny compared to actually solving the problem. But feel free to prove me wrong !

@lovasoa
lovasoa merged commit 7cf87be into rust-or:master Jan 9, 2026
2 checks passed
@lovasoa

lovasoa commented Jan 9, 2026

Copy link
Copy Markdown
Contributor

Thanks, merged !

lovasoa added a commit that referenced this pull request Jan 9, 2026
* Defined WithMipStart trait

* Implemented WithMipStart for GurobiSolver

* fix test case: Replaced use of hardcoded /tmp directory with temp_dir() call
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.

2 participants