CPMpy

Getting started:

  • Modeling and solving with CPMpy
  • Summary sheet

Advanced guides:

  • How to debug
  • Obtaining multiple solutions
  • Solving with assumptions
  • Developer guide
  • Adding a new solver
  • Test Suite

API documentation:

  • Model (cpmpy.model)
  • Expressions (cpmpy.expressions)
  • Expression transformations (cpmpy.transformations)
  • Solver interfaces (cpmpy.solvers)
  • Tools (cpmpy.tools)
CPMpy
  • Setting solver parameters and hyperparameter search
  • View page source

Setting solver parameters and hyperparameter search

Calling a solver by name

You can see the list of available solvers (and subsolvers) as follows:

from cpmpy import *

print(SolverLookup.solvernames())

On my system, with pysat and minizinc installed, this gives `[‘ortools’, ‘minizinc’, ‘minizinc:chuffed’, ‘minizinc:coin-bc’, …, ‘pysat:minicard’, ‘pysat:minisat22’, ‘pysat:minisat-gh’]

You can use any of these solvers by passing its name to the Model.solve() parameter ‘solver’ as such:

a,b = boolvar(2)
Model(a|b).solve(solver='minizinc:chuffed')

Setting solver parameters

OR-tools has many solver parameters, documented here.

CPMpy’s interface to ortools accepts keyword arguments to solve(), and will set the corresponding or-tools parameters if the name matches. We documented some of the frequent once in our CPM_ortools API.

For example, with model a CPMpy Model(), you can do the following to make or-tools use 8 parallel cores and print search progress:

from cpmpy import *
from cpmpy.solvers import CPM_ortools

s = CPM_ortools(model)
s.solve(num_search_workers=8, log_search_progress=True)

Hyperparameter search across different parameters

Because CPMpy offers programmatic access to the solver API, hyperparameter search can be straightforwardly done with little overhead between the calls.

The tools directory contains a utility to efficiently search through the hyperparameter space defined by the solvers tunable_params. This utlity is based on the SMBO framework and speeds up the search by implementing adaptive capping.

The parameter tuner is based on the following publication:

Ignace Bleukx, Senne Berden, Lize Coenen, Nicholas Decleyre, Tias Guns (2022). Model-Based Algorithm Configuration with Adaptive Capping and Prior Distributions. In: Schaus, P. (eds) Integration of Constraint Programming, Artificial Intelligence, and Operations Research. CPAIOR 2022. Lecture Notes in Computer Science, vol 13292. Springer, Cham. https://doi.org/10.1007/978-3-031-08011-1_6

In the following example, we tune the OR-tools solver.

from cpmpy import *
from cpmpy.tools import ParameterTuner

model = Model(...)

tuner = ParameterTuner("ortools", model)
best_params = tuner.tune(max_tries=100)
print(f"Tuner reduced runtime from {tuner.base_runtime}s to {tuner.best_runtime}s")

# now solve (a slightly different?) model using the best parameters
solver = SolverLookup.get("ortools", model)
solver.solve(**best_params)

However, solverinterfaces are not required to present a list of tunable parameters and the tool allows you to define the set of tunable parameters (and values) yourself.

from cpmpy import *
from cpmpy.tools import ParameterTuner

model = Model(...)

tunables ={
   "MIPFocus": [0,1,2,3],
   "Method" : [-1, 0, 1,2,3,4,5],
   "FlowCoverCuts" :[-1,0,1,2]
}
defaults = {
    "MIPFocus": 0,
    "Method": -1,
    "FlowCoverCuts": -1
}

tuner = ParameterTuner("gurobi", model, tunables, defaults)
print(f"Tuner reduced runtime from {tuner.base_runtime}s to {tuner.best_runtime}s")

best_params = tuner.tune(time_limit=10)

solver = SolverLookup.get("gurobi", model)
solver.solve(**best_params)

© Copyright 2026, Tias Guns.

Built with Sphinx using a theme provided by Read the Docs.