Changes since 1.17.1
LinExpr.add_varandxsumhot paths optimised (single dict operation instead of two; bypass dispatch overhead for the commonVar-only case), cutting 11–21% off constraint-heavy model build times.- HiGHS backend gained a CFFI C-array cache (matching CBC's bulk-add architecture) that
accumulates pending columns/rows and flushes via
Highs_addCols/Highs_addRows, plus name→index dicts to avoid unnecessary flushes on variable/constraint lookups. - Anonymous variables no longer pay the
str.format/str.encodecost of auto-generatedvar(N)names.
A new reproducible benchmark suite (benchmarks/, documented in docs/bench.rst) was added to
measure and track these improvements — comparing python-mip/CBC, python-mip/HiGHS, and
python-mip/Gurobi model-build speed across CPython 3.14 and PyPy 3.11, against raw gurobipy
and highspy (high-level and batch-numpy APIs), on four problems (n-Queens, TSP, RCPSP, and the
new Capacitated Facility Location Problem). Highlights:
- python-mip/Gurobi on PyPy is 2–4× faster than on CPython, depending on model structure, and
remains the only way to drive Gurobi from PyPy at all (
gurobipyhas no PyPy wheel). - For sparse, variable-heavy models python-mip/Gurobi is competitive with or faster than raw
gurobipyeven on CPython; for dense-constraint modelsgurobipy's own loop is faster on CPython, but PyPy closes much of that gap. - Against
highspy's own recommended vectorized numpy-array API, python-mip/HiGHS is competitive with or faster than it on sparser/irregular problems (n-Queens, TSP), while the vectorized API pulls ahead on dense, rectangular problems (e.g. CFLP).
Model.add_vars(n, ...) / VarList.add_vars(n, ...) create n variables in a single call,
avoiding per-call dispatch overhead compared to n calls to add_var().
OptimizationStatus.TRUNCATEDfor LP solves stopped early by a time or iteration limit (populates primal/dual solution and objective bound whenever feasible, instead of reporting a misleadingOPTIMAL/INFEASIBLE).Model.max_itercaps simplex/barrier iterations for LP solves, wired through CBC, HiGHS and Gurobi.Model.optimize(lp_method=...)selects dual simplex, primal simplex or IPM/barrier — added to HiGHS and Gurobi (CBC already had it).- New CBC-specific
LP_Method.RACINGandLP_Method.RECOMMENDvalues:RACINGruns several LP configurations (dual simplex, primal/Idiot, primal/Sprint) in parallel threads and keeps the first to reach optimality (needsModel.threads >= 2; safely degrades toRECOMMENDwith a log message if fewer threads are available);RECOMMENDuses CBC's ML-based per-instance LP method selection. Both are ignored (fall back to their own default) by HiGHS and Gurobi.LP_Method.AUTO(the default) already delegates toRECOMMENDwhen sequential andRACINGwhen 2+ threads are set, so no behaviour changes for existing code — these are purely new, explicit opt-in values. Model.optimize(relax=True, lp_preprocess=True)(CBC-specific) enables CBC'sINT_PARAM_LP_FAST_PREPROCESSknapsack bound-tightening before an LP relaxation solve.
cbcboxbumped to>=2.935, improving binary reliability across platforms.- HiGHS backend migrated to
highspy; addedTRUNCATEDstatus andmax_iter/lp_method(dual/primal simplex, IPM/barrier) support, also ported to the Gurobi backend. - Python 3.14 added to the CI test matrix (alongside 3.10–3.13 and PyPy 3.11).
- CBC string parameters migrated to the
INT_PARAMAPI; fixedverbosereset onclear(). - Removed an obsolete objective-sense save/restore workaround around
Cbc_reset(). - Stale
highspy→highsboxerror message corrected.
python-mip now ships with full support for the HiGHS open-source solver as a first-class backend (alongside CBC and Gurobi). HiGHS is a high-performance solver for LP and MIP problems with a permissive MIT licence.
Key capabilities added:
- Full LP and MIP solve via HiGHS C API (through
highsbox) - Warm-start (basis handoff) for LP re-solves
relax=Truesupport inoptimize()- Variable and constraint inspection/modification
- Correct handling of
UNBOUNDEDvsINFEASIBLEstatus - Reduced memory footprint and improved file read/write consistency
HiGHS is installed as an optional dependency: pip install mip[highs].
CBC now runs natively on Apple Silicon via a pre-built ARM64 binary, replacing the previous Rosetta 2 x86_64 fallback.
The bundled CBC shared libraries (.so, .dylib, .dll) have been removed from the
python-mip source tree. CBC binaries are now distributed through the
cbcbox PyPI package, which provides pre-built wheels for:
- Linux x86_64 and aarch64 (ARM64)
- macOS x86_64 and arm64
- Windows x64
cbcbox is a dedicated package whose sole job is to ship up-to-date CBC binaries for all
major platforms. This decoupling means future CBC upgrades are released without touching
python-mip itself. The minimum required version is cbcbox>=2.902.
A new GitHub Actions workflow (.github/workflows/publish.yml) automatically publishes to
PyPI whenever a v* tag is pushed. It uses OIDC Trusted Publisher authentication — no API
tokens to rotate.
| Platform | OS |
|---|---|
| Linux x86_64 | ubuntu-24.04 |
| Linux aarch64 | ubuntu-24.04-arm (new) |
| macOS ARM64 | macos-15 (new) |
| Windows x64 | windows-2025 (new) |
Python versions tested: 3.10, 3.11, 3.12, 3.13, PyPy 3.11.
- CBC re-solve correctness: A bug introduced by newer CBC versions caused stale solution
data to be returned when
optimize()was called multiple times on the same model. Fixed by callingCbc_reset()before eachCbc_solve(), with objective sense saved and restored around the reset. isfileimport missing inSolverCbc.read():os.path.isfilewas used but not imported, causing aNameErrorwhen loading a model from a file.- Windows DLL loading: On Python 3.8+, Windows ignores
PATHwhen resolving DLL dependencies. Fixed by callingos.add_dll_directory()on the cbcboxbin/directory. - Empty
LinExprin constraints: Constraints containing an empty linear expression were not handled correctly. Fixed by Sebastian Heger (#237).
- Minimum Python version raised to 3.10. Python 3.8 and 3.9 have reached end-of-life and are no longer tested or supported.
- Bundled CBC libraries removed —
cbcboxis now a required dependency (installed automatically via pip). gurobipyversion constraint relaxed to>=10(no upper bound).cffiversion constraint relaxed to>=1.15(no upper bound).highsboxversion constraint relaxed to>=1.10.0(no upper bound).
This release was a team effort. Thank you to everyone who contributed:
- Robert Schwarz — HiGHS interface: initial implementation (PR #332) and extensive
improvements (PR #418), including objective setter fix, option types, test coverage and
highsboxmigration. Co-authored with Bernard Zweers and Miguel Hisojo. - Túlio Toffolo — macOS Apple Silicon support, HiGHS testing infrastructure, CI modernisation, and many quality-of-life fixes.
- Sebastian Heger — Bug fix for constraints with empty linear expressions (#237).
- Dominik Peters — Removed upper limit on supported Python versions (#408).
- Adeel Khan — HiGHS
_corelibrary support. - Haroldo Santos — cbcbox integration, CBC bug fixes, CI/CD automation, and release management.