Solver Backends

PyEPO separates the training frontend from the optimization backend. A backend supplies the optModel interface: update the objective with setObj and solve with solve. Training methods depend only on this interface, so the same training code can run on any backend.

Supported Backends

Backend

License

Problem classes

Notes

gurobi

commercial, free academic license

LP, MIP, QP, quadratic constraints

default backend with lazy-constraint callbacks (TSP DFJ, VRP RCI) and cut recycling

copt

commercial, free academic license

LP, MIP, QP, quadratic constraints

callback support matches Gurobi

pyomo

open (the modeling layer)

whatever the chosen solver supports

solver= names the engine: GLPK, CBC, HiGHS, SCIP, or a licensed solver. QP needs a QP-capable solver

ortools

open

LP, MIP (no quadratics)

pywraplp with solver= (default "scip"). The CP-SAT variant handles integer-only models

mpax

open

LP, QP

JAX-based first-order (PDHG) solver on GPU. Solves whole batches at once. Continuous only: integer variables are relaxed with a warning

Selecting a Backend

The DSL compile and the built-in model factories take a backend keyword, so the same problem definition runs on any installed backend:

optmodel = prob.compile(backend="gurobi")
optmodel = prob.compile(backend="pyomo", solver="appsi_highs")   # open solver
optmodel = prob.compile(backend="mpax")                          # LP/QP on GPU

model = pyepo.model.shortestPathModel(grid)                      # default Gurobi
model = pyepo.model.shortestPathModel(grid, backend="ortools", solver="scip")

Solver Parameters

compile and the model factories forward keyword arguments to the backend. timelimit= (seconds) sets a time limit where supported. Other keywords pass through as native solver parameters where the backend accepts them.

prob.compile(backend="gurobi", timelimit=10)
prob.compile(backend="gurobi", MIPGap=0.01)

The full per-backend keyword table is in DSL Models.

MPAX: GPU Batch Solving

MPAX solves an entire mini-batch in one GPU dispatch, so optDataset construction and each training step avoid the per-instance solver loop. With the JAX frontend, the solve is traceable and the whole training step compiles under jax.jit (see JAX Frontend). The PyTorch frontend uses the same batched solve through a DLPack bridge. PDHG is a continuous first-order method, so integer and binary variables are relaxed to their bounds. Solutions may therefore be fractional. PyEPO warns when this relaxation is used.