Solvers¶
Pass a solver code to the CLI with --solver <code>. OR-Tools/CP-SAT is the
default and the only recommended backend. Other backends are experimental or
limited.
Support matrix¶
OR-Tools¶
| Solver | Selector | API | Platforms | Level |
|---|---|---|---|---|
| CP-SAT | ortools/cp-sat |
cp_model.CpModel and CpSolver |
π§ π πͺ | Recommended |
| CBC | ortools/mpsolver/cbc |
pywraplp.Solver (MPSolver) |
π§ π πͺ | Experimental |
| SCIP | ortools/mpsolver/scip |
pywraplp.Solver (MPSolver) |
π§ π πͺ | Experimental |
| CP-SAT | ortools/mpsolver/cp-sat |
pywraplp.Solver (MPSolver) |
π§ π πͺ | Experimental |
| BOP | ortools/mpsolver/bop |
pywraplp.Solver (MPSolver) |
π§ π πͺ | Limited |
| GSCIP | ortools/mathopt/gscip |
mathopt.Model |
π§ π πͺ | Experimental |
| CP-SAT | ortools/mathopt/cp-sat |
mathopt.Model |
π§ π πͺ | Experimental |
| HiGHS | ortools/mathopt/highs |
mathopt.Model |
π§ π πͺ | Experimental |
PuLP¶
| Solver | Selector | API | Platforms | Level |
|---|---|---|---|---|
| CBC | pulp/cbc |
pulp.LpProblem |
π§ π πͺ | Experimental |
| cuOpt | pulp/cuopt |
pulp.LpProblem |
π§ | Experimental |
| GLPK | pulp/glpk |
pulp.LpProblem |
π§ π πͺ | Limited |
| HiGHS | pulp/highs |
pulp.LpProblem |
π§ πͺ | Experimental |
| SCIP | pulp/scip |
pulp.LpProblem |
π§ πͺ | Experimental |
π§ is Linux, π is macOS, and πͺ is Windows. Only validated platforms are shown.
Recommended is the default. Experimental is tested but not recommended. Limited is intended only for small or bounded cases.
- Linux and Windows coverage is x86_64 only. ARM validation is pending.
- PuLP/CBC is unsuitable for the large 87-person real scenario because it cannot reliably find an incumbent within the bounded test window. Its timeout capability is still tested on that scenario. Only its intermediate-score capability uses a minimal testcase.
- PuLP/cuOpt is tested on Linux and requires the NVIDIA cuOpt runtime and a supported GPU. macOS has no supported GPU runtime. Windows validation is pending.
- PuLP/GLPK requires
glpsol. - PuLP/GLPK uses smoke coverage because some full regression models take several minutes without proving optimality.
- PuLP/HiGHS is skipped on macOS because its native library may conflict with the HiGHS library bundled with OR-Tools in the same Python process. Observed failure in GitHub runners, should investigate further in the future.
- PuLP/SCIP validation on macOS is pending.
- MPSolver/BOP is a legacy engine intended only for small cases.
Runtime capabilities¶
The server exposes Cancel for every running or queued job. Finish now is available only when the selected solver supports returning its current result.
| Selector | Graceful timeout | Finish now | Intermediate score events |
|---|---|---|---|
ortools/cp-sat |
Yes | Yes | Yes |
ortools/mpsolver/cbc |
No | No | No |
ortools/mpsolver/scip |
No | No | No |
ortools/mpsolver/cp-sat |
No | No | No |
ortools/mpsolver/bop |
No | No | No |
ortools/mathopt/gscip |
No | No | No |
ortools/mathopt/cp-sat |
No | No | No |
ortools/mathopt/highs |
No | No | No |
pulp/cbc |
No | No | Yes |
pulp/cuopt |
Yes | No | Yes |
pulp/glpk |
No | No | No |
pulp/highs |
No | No | No |
pulp/scip |
No | No | No |
Note: Capabilities have been manually confirmed only for
ortools/cp-sat,pulp/cuopt, andpulp/cbc. Other backends remain unconfirmed and are left for future verification.
Graceful timeout means the solver is confirmed to observe the requested limit and return on its own. Server-enforced timeout is global, so it is not stored as a solver capability. Yes means the trait is confirmed and enabled in the server registry. No means it is not confirmed and does not prove that the underlying solver cannot support it.
Server configuration¶
GET /optimize/options publishes the solver choices and defaults accepted by
one backend deployment. Solver labels, compute type, and finish-now support
come from the same capability registry as the supported selectors above.
Every advertised solver includes the deployment's integer timeout range and
running cancellation because the server enforces both at the process level.
Configure the ordered solver subset and defaults with:
OPTIMIZE_SOLVERS=ortools/cp-sat,pulp/cuopt
OPTIMIZE_DEFAULT_SOLVER=ortools/cp-sat
OPTIMIZE_MIN_TIMEOUT_SECONDS=1
OPTIMIZE_DEFAULT_TIMEOUT_SECONDS=300
OPTIMIZE_MAX_TIMEOUT_SECONDS=3600
OPTIMIZE_DEFAULT_PRETTIFY=true
The default deployment advertises only ortools/cp-sat. Configure
pulp/cuopt only where its GPU runtime is available. The server fails startup
when an advertised solver runtime is unavailable.
PuLP/CBC on the large scenario¶
With the bundled CBC 2.10.3, the 87-person model has about 74,000 variables and 100,000 constraints. A 10-second run spends its budget in the root relaxation and preprocessing without entering branch-and-bound or producing an integer incumbent. Default preprocessing has also reported the known-feasible model as infeasible or unbounded. Disabling preprocessing avoids that early report, but the solver can then overrun its internal time limit before integer search starts. The missing intermediate result is therefore solver behavior, not a progress-log parsing failure.
Keep PuLP/CBC classified as unsuitable for this scenario until its formulation or runtime behavior improves. The capability probe intentionally uses the minimal testcase only to confirm that CBC intermediate-score reporting works on a model it can solve.
Finish now asks the solver to stop and preserves its current feasible
schedule. The job fails without an artifact if interruption occurs before a
feasible schedule exists. Cancel discards any result and marks the job as
cancelled by immediately terminating its optimization process. Cancellation
uses error code cancelled and never preserves an artifact.
Intermediate score events are emitted before the solver returns. Native
OR-Tools CP-SAT reports incumbents through solution callbacks. PuLP/CBC and
PuLP/cuOpt derive incumbent scores from solver logs. Other backends emit a
score event only with their final feasible result. A solver-native time limit
preserves a feasible schedule when one is available. A forced watchdog timeout
fails without an artifact because the schedule is not checkpointed outside the
child process. These paths are reported as solver_timeout and
process_timeout, respectively. A solver registered for graceful timeout fails
the capability probe if the watchdog must terminate it.
Validate these capabilities against the large real scenario on the current platform:
cd core
python tests/real/solver_capabilities.py --solver ortools/cp-sat
python tests/real/solver_capabilities.py --all \
--json-output solver-capabilities.json
The probe runs timeout and each other confirmed trait as a separate subprocess.
The intermediate-score round uses the basic one-person, one-day testcase only
for PuLP/CBC. Other solvers use the large real scenario. Missing platform
runtimes are reported as UNAVAILABLE rather than stopping the remaining
checks.
Test coverage¶
Test filenames below are relative to core/tests/.
Low-level tests¶
| API | Test File |
|---|---|
| OR-Tools CP-SAT | test_solver_ortools_cp_sat.py |
| OR-Tools MPSolver | test_solver_ortools_linear.py |
| OR-Tools MathOpt | test_solver_ortools_mathopt.py |
| PuLP/CBC | test_solver_pulp_cbc.py |
| PuLP/cuOpt | test_solver_pulp_cuopt.py, skipped in CI |
| PuLP/GLPK | test_solver_pulp_glpk.py |
| PuLP/HiGHS and SCIP | test_solver_pulp_python.py |
Schedule tests¶
| Selector | Coverage | Test File | Real Test |
|---|---|---|---|
ortools/cp-sat |
Full | test_schedule_ortools_cp_sat.py |
real/schedule_ortools_cp_sat.py |
ortools/mpsolver/cbc |
Basic | test_schedule_ortools_mpsolver_cbc.py |
β |
ortools/mpsolver/scip |
Basic | test_schedule_ortools_mpsolver_scip.py |
β |
ortools/mpsolver/cp-sat |
Basic | test_schedule_ortools_mpsolver_cp_sat.py |
β |
ortools/mpsolver/bop |
Smoke | test_schedule_ortools_mpsolver_bop.py |
β |
ortools/mathopt/gscip |
Basic | test_schedule_ortools_mathopt_gscip.py |
β |
ortools/mathopt/cp-sat |
Basic | test_schedule_ortools_mathopt_cp_sat.py |
β |
ortools/mathopt/highs |
Basic | test_schedule_ortools_mathopt_highs.py |
β |
pulp/cbc |
Basic and XLSX | test_schedule_pulp_cbc.py, test_export_xlsx_pulp_cbc.py |
real/schedule_pulp_cbc.py, skipped |
pulp/cuopt |
Basic, skipped in CI | test_schedule_pulp_cuopt.py |
real/schedule_pulp_cuopt.py, skipped |
pulp/glpk |
Smoke | test_schedule_pulp_glpk.py |
β |
pulp/highs |
Basic, skipped on macOS | test_schedule_pulp_highs.py |
β |
pulp/scip |
Basic | test_schedule_pulp_scip.py |
β |
Full coverage includes Basic coverage and an enabled real-scenario test. Basic
coverage runs every non-real YAML fixture. It normally solves each valid case
again while avoiding the first solution, then checks the expected schedule.
Smoke coverage uses one representative scenario with a fixed timeout. Tests
under core/tests/real/ are explicit, slower checks outside the normal test
discovery rules.
Excluded backends¶
Commercial or proprietary integrations such as CPLEX, Gurobi, MOSEK, XPRESS, COPT, SAS, and MIPCL are intentionally excluded from the standard environment.
OR-Tools¶
- Continuous solvers such as GLOP, CLP, and PDLP cannot represent this project's binary and integer scheduling model.
- MathOpt/GLPK is not bundled in the OR-Tools Python wheel. GLPK is exposed through PuLP instead.
- Additional aliases for the same engine are omitted unless they provide a useful API or test boundary.
PuLP¶
- CyLP is excluded because PuLP 3.3.2 loses the maximization sense while passing its MPS model to CyLP, which can return a minimized schedule as βOptimal.β
COIN_CMD,HiGHS_CMD,SCIP_CMD, andFSCIP_CMDrequire separate executables and mostly duplicate supported CBC, HiGHS, and SCIP engines.PYGLPKandCOINMP_DLLare unavailable legacy integrations. GLPK is supported throughGLPK_CMD.CHOCO_CMDrequires Java and a separately managed parser JAR, neither of which is part of the project environment.- PuLP's CP-SAT integration is not present in the pinned PuLP 3.3.2 release. The native OR-Tools/CP-SAT backend is already the recommended default.