Skip to main content

OptalCP 2026.1.0 Release

This release introduces a native Python API, bringing OptalCP to a wider audience of optimization practitioners. The TypeScript API has been refined to align with the new Python interface, resulting in cleaner, more intuitive syntax across both languages.

On the solver side, we've added automatic configuration through presets, making it easier to get good performance without manual parameter tuning. Decision problems now stop automatically after finding the first solution, eliminating a common source of confusion. Discrete resource constraints now support variable maximum capacity, enabling new classes of capacity planning problems.

Highlights

New Python API

OptalCP now has a Python API. The API is designed to be nearly identical to the TypeScript API, making it easy to switch between languages or translate examples.

import optalcp as cp

model = cp.Model()
task = model.interval_var(length=10, name="task")
model.minimize(task.end())

result = model.solve(cp.Parameters(timeLimit=60))
if result.solution:
print(f"Task ends at {result.solution.get_end(task)}")

Key features:

  • Method-based style: model.solve()
  • Property accessors: interval.start_min, interval.length_max
  • Comparison operators: cumul <= 10 and 5 < x
  • Auto-registration of constraints and objectives

TypeScript API Changes

The TypeScript API has been updated to align with the new Python API. Both APIs now share nearly identical syntax. The main changes are:

  • model.constraint() renamed to model.enforce() for clarity
  • solve(model, ...) replaced by model.solve()
  • Functions merged into overloads: model.cumulPlus() is now just model.plus(), working for both integer and cumulative expressions
  • Getter/setter methods replaced with properties
  • And many more...

Old functions remain available but are deprecated. See TypeScript API Changes below for the full list.

Automatic Solver Configuration with Presets

The new preset parameter simplifies solver configuration by setting optimal defaults for multiple parameters at once:

  • Auto (default): Automatically selects preset based on problem size
  • Default: Balanced configuration with maximum propagation and mixed search strategies
  • Large: Optimized for problems with more than 100,000 variables

Variable Capacity for Discrete Resources

Discrete resource constraints now support variable maximum capacity. Instead of a fixed integer limit, you can specify a decision variable or expression as the capacity bound:

# Variable capacity based on a decision variable
capacity = model.int_var(min=5, max=10, name="capacity")
model.enforce(cumul <= capacity)

This enables modeling scenarios where resource capacity itself is a decision, such as:

  • Selecting machine configurations with different capacities
  • Optimizing workforce allocation where team size varies
  • Capacity planning problems where investment decisions affect limits

Smart Default for Decision Problems

The solutionLimit parameter now defaults to automatic mode: decision problems (without an objective) stop after finding the first solution, while optimization problems continue searching. This eliminates the common pitfall of forgetting to set solutionLimit=1 for satisfaction problems.

New Features

Solver

  • Variable resource capacity: Discrete resource constraints now accept decision variables or expressions as capacity bounds
  • Preset parameter: One-parameter solver configuration for different problem sizes
  • Automatic solution limit: Smart default stops at first solution for decision problems
  • Deferred solution values: Performance optimization for large models
  • Improved logging: Parameter values now show reasons (preset, auto) and workers are grouped by configuration
  • solverArgs parameter: Pass custom command-line arguments to the solver subprocess

TypeScript API Changes (Detail)

The main goal of these changes is to align the TypeScript and Python APIs, making them nearly identical and easier to use across both languages.

All deprecated functions remain functional but are no longer documented. They will be removed in a future release.

Summary of Changes

CategoryChange Pattern
Variable propertiesMethods → Property accessors
Cumulative expressionscumul prefix removed
Step functionsstepFunction prefix removed, clearer names
Interval accessorsOf suffix removed
Global functionsMoved to class methods
Event handlerson() method → Property setters
Result propertiesRenamed for clarity

Variable Classes

Variable properties are now accessed directly as properties instead of through getter/setter methods, making the code more concise and idiomatic.

IntVar

DeprecatedReplacement
isOptional()optional property
isPresent()optional property
isAbsent()optional property
getMin()min property
getMax()max property
makeOptional()optional = true
makeAbsent()optional = null
makePresent()optional = false
setMin(min)min property
setMax(max)max property
setRange(min, max)min and max properties

BoolVar

DeprecatedReplacement
isOptional()optional property
isPresent()optional property
isAbsent()optional property
getMin()min property
getMax()max property
makeOptional()optional = true
makeAbsent()optional = null
makePresent()optional = false
setMin(min)min property
setMax(max)max property
setRange(min, max)min and max properties

IntervalVar

DeprecatedReplacement
isOptional()optional property
isPresent()optional property
isAbsent()optional property
makeOptional()optional = true
makePresent()optional = false
makeAbsent()optional = null
getStartMin()startMin property
getStartMax()startMax property
getEndMin()endMin property
getEndMax()endMax property
getLengthMin()lengthMin property
getLengthMax()lengthMax property
setStart(s)startMin and startMax properties
setStart(sMin, sMax)startMin and startMax properties
setStartMin(sMin)startMin property
setStartMax(sMax)startMax property
setEnd(e)endMin and endMax properties
setEnd(eMin, eMax)endMin and endMax properties
setEndMin(eMin)endMin property
setEndMax(eMax)endMax property
setLength(len)lengthMin and lengthMax properties
setLength(lMin, lMax)lengthMin and lengthMax properties
setLengthMin(lMin)lengthMin property
setLengthMax(lMax)lengthMax property

ModelElement

DeprecatedReplacement
setName(name)name property
getName()name property

Model Class

Naming and Constraints

The constraint() method is renamed to enforce() to better convey the intent of adding a constraint to the model.

DeprecatedReplacement
setName(name)name property
getName()name property
constraint(constraint)enforce(constraint)
intVar({ range: [a, b] })intVar({ min: a, max: b })

Interval Accessors

The Of suffix is removed from interval accessor functions for cleaner syntax.

DeprecatedReplacement
presenceOf(interval)presence(interval)
startOf(interval)start(interval)
endOf(interval)end(interval)
lengthOf(interval)length(interval)

Cumulative Expressions

The cumul prefix is removed; these functions are now overloaded with their integer counterparts (e.g., plus() works for both integers and cumulative expressions).

DeprecatedReplacement
cumulSum(args)sum(args)
cumulPlus(lhs, rhs)plus(lhs, rhs)
cumulMinus(lhs, rhs)minus(lhs, rhs)
cumulLe(cumul, max)le(cumul, max)
cumulGe(cumul, min)ge(cumul, min)
cumulNeg(arg)neg(arg)

Step Functions

Step function operations are renamed to use standard mathematical terminology.

DeprecatedReplacement
stepFunctionSum(func, interval)integral(func, interval)
stepFunctionEval(func, x)eval(func, x)

CumulExpr Class

Instance methods mirror the model-level changes, removing the cumul prefix.

DeprecatedReplacement
cumulPlus(rhs)plus(rhs)
cumulMinus(rhs)minus(rhs)
cumulLe(max)le(max)
cumulGe(min)ge(min)
cumulNeg()neg()

IntStepFunction Class

Instance methods mirror the model-level changes, using standard mathematical names.

DeprecatedReplacement
stepFunctionSum(interval)integral(interval)
stepFunctionEval(x)eval(x)

Solver Class

Event Handlers

Event handlers are now assigned as properties instead of using the on() method.

DeprecatedReplacement
on('error', listener)onError property
on('warning', listener)onWarning property
on('log', listener)onLog property
on('solution', listener)onSolution property
on('objectiveBound', listener)onObjectiveBound property
on('lowerBound', listener)onObjectiveBound property
on('summary', listener)onSummary property

Result Types

SolveSummary

Field names are updated for consistency: lowerBound becomes objectiveBound to reflect that it applies to both minimization and maximization.

DeprecatedReplacement
nbWorkersactualWorkers
lowerBoundobjectiveBound

SolveResult

The best prefix is removed from field names for brevity, and lowerBound becomes objectiveBound.

DeprecatedReplacement
nbWorkersactualWorkers
lowerBoundobjectiveBound
bestSolutionsolution
bestSolutionTimesolutionTime
bestLBTimeboundTime
bestSolutionValidsolutionValid
lowerBoundHistoryobjectiveBoundHistory

Global Functions

Standalone functions are moved to class methods for better discoverability and a more object-oriented API.

DeprecatedReplacement
calcSolverPath(params)Solver.findSolver(params)
solve(model, params, ...)model.solve(params, ...)
problem2json(model)model.toJSON()
json2problem(json)Model.fromJSON(json)
problem2txt(model, ...)model.toText(...)
problem2js(model, ...)model.toJS(...)

Parameter Parsing

The CLI parameter parsing API has been redesigned to use an options object for better flexibility and consistency.

DeprecatedReplacement
parseParameters(params?, args?)parseParameters(options?)
parseSomeParameters(params, args?)parseKnownParameters(options?)
Parameters.versionRemoved (use --optalcpVersion flag)
Parameters.usageparseParameters({ usage: "..." })

The new functions use an options object:

const params = parseParameters({
args: process.argv.slice(2), // default
defaults: { timeLimit: 60 }, // CLI overrides these
usage: "Usage: myapp [options]",
exitOnError: true // false to throw instead of exit
});

const [params, unknown] = parseKnownParameters({ ... });

The --version flag has been renamed to --optalcpVersion to print solver version information.

Type Aliases (Backward Compatibility)

These type aliases are preserved for backward compatibility but should be migrated to the new names.

DeprecatedReplacement
ModelNodeModelElement
ObjectiveHistoryItemObjectiveEntry
LowerBoundEventObjectiveBoundEntry

Solver Parameter Changes

Deprecated (Backward Compatible)

The LB (lower bound) terminology is replaced with Dual to be consistent with optimization literature.

DeprecatedReplacement
FDSLBFDSDual

Breaking Changes (No Backward Compatibility)

These parameter renames are not backward compatible; old names will cause errors.

Old NameNew Name
FDSLBStrategyFDSDualStrategy
FDSLBResetRatingsFDSDualResetRatings
logOutputprintLog
solverPathsolver
stepFunctionSumPropagationLevelintegralPropagationLevel