Choosing a solver¶
Every backend exposes the same modeling interface, so the choice of solver is a two-line change. This page lists the available backends, how to switch between them, and what each one supports.
The backends¶
Each backend lives in mippp/solvers/<name>/all.hpp and provides an api class plus one model class per problem kind. The version in the alias points at the solver release the binding targets.
| Solver | Header (mippp/solvers/…) |
API class | Model classes | Targets |
|---|---|---|---|---|
| HiGHS | highs/all.hpp |
highs_api |
highs_lp, highs_milp, highs_qp |
v1.10 |
| Gurobi | gurobi/all.hpp |
gurobi_api |
gurobi_lp, gurobi_milp |
v12.0 |
| CPLEX | cplex/all.hpp |
cplex_api |
cplex_lp, cplex_milp |
v22.12 |
| FICO Xpress | xpress/all.hpp |
xpress_api |
xpress_lp, xpress_milp |
v45.1 |
| COPT | copt/all.hpp |
copt_api |
copt_lp, copt_milp |
v7.2 |
| MOSEK | mosek/all.hpp |
mosek_api |
mosek_lp, mosek_milp |
v11 |
| SCIP | scip/all.hpp |
scip_api |
scip_milp |
v8 |
| Cbc | cbc/all.hpp |
cbc_api |
cbc_milp |
v2.10.12 |
| Clp | clp/all.hpp |
clp_api |
clp_lp |
v1.17 |
| GLPK | glpk/all.hpp |
glpk_api |
glpk_lp, glpk_milp |
v5 |
| SoPlex | soplex/all.hpp |
soplex_api |
soplex_lp |
v6 |
Notes:
*_lpclasses model continuous problems;*_milpclasses add integer and binary variables (a*_milpmodel with only continuous variables is of course a valid LP). SCIP and Cbc expose only a MILP class; Clp and SoPlex only an LP class.- Quadratic objectives (
*_qp) are currently supported through HiGHS only.
Switching backends¶
The examples follow one convention: the backend appears in exactly three places — the include and two aliases.
Change those to gurobi/gurobi_api/gurobi_milp and recompile: the rest of the program is untouched. There is no linking step to adjust, because solver libraries are loaded at runtime.
To choose the solver at runtime — for a --solver command-line flag, say — write the model-building code once as a template over the backend and dispatch on the flag; that pattern, and the capability checks that go with it, are the subject of Writing solver-generic code.
Only the solvers actually installed on the machine need to be present: a backend fails at api-construction time (with a descriptive exception), not at program startup.
How solver libraries are found¶
Constructing the api object loads the solver's shared library throughdylib. Resolution order (first match wins):
- an explicit path passed to the constructor —
gurobi_api api("/opt/gurobi1201/linux64/lib/libgurobi120.so"); - the
MIPPP_<SOLVER>_LIBRARYenvironment variable, holding the full path of the exact file to load; - a search of the dynamic loader's directories (
LD_LIBRARY_PATHand system library paths) for the conventional name, accepting version-suffixed sonames (libhighs.so.1.10.0) when the plain name is absent.
See Installation for per-solver environment setup.
Feature support¶
Core LP/MILP modeling works on every backend. Optional capabilities — dual solutions, callbacks, MIP starts, SOS and indicator constraints, parameter control — vary; each is a concept, so code that needs one states it and the compiler enforces it.
The matrices below record which features are implemented and tested per backend (generated from the test suites).
MILP models¶

LP models¶

Notable current limitations (see the roadmap for what's planned):
- Callbacks — candidate-solution callbacks are implemented on Gurobi, CPLEX, COPT, SCIP and Xpress, and validated on Gurobi, CPLEX and COPT. Node-relaxation (user-cut) callbacks are specified but not yet implemented.
- Solve status —
solve_status()is part oflp_model, so every backend reports one, but the set of tags a backend can return varies (it is part of the model type).refine_lp_status()— resolvinginfeasible_or_unboundedinto one of the two — exists only ongurobi_lpandcplex_lp, andglpk_milpcannot yet reportinfeasible. See Status, limits and tolerances. - Quadratic objectives — HiGHS only. Quadratic constraints: none yet.
- SOS constraints and LP basis warm starts — specified as concepts, not yet implemented by any backend.
- Indicator constraints — usable on Gurobi and CPLEX by calling
add_indicator_constraintdirectly, buthas_indicator_constraintsisfalseeverywhere because those implementations returnvoidwhere the concept expects a constraint handle (details). - Solver-specific parameters — the uniform interface covers limits and tolerances, but there is no passthrough yet for solver-specific knobs such as Gurobi's
MIPFocusor CPLEX's emphasis settings. The*_apiobject you construct exposes every raw C function it loads, so the functions are reachable — but the model classes keep their native model and environment handlesprotected, so there is currently no supported escape hatch to call them on your model. A public native-handle accessor is on the roadmap; until it lands, a uniform interface is all you get, and research that depends on solver-specific tuning should account for that.
Next¶
Writing solver-generic code — one model builder, every backend, with capability differences resolved at compile time.