# @scheduleopt/optalcp

## Classes

- BoolExpr
- CumulExpr
- FloatExpr
- IntExpr
- IntStepFunction
- IntervalVar
- Model
- ModelDomains
- ModelNode
- SequenceVar
- Solution
- Solver

## Parameters

### Parameters

Ƭ **Parameters**: `Object`

Parameters allow to specify how the solver should behave. For example, the number of workers (threads) to use, the time limit, etc.

Parameters can be passed to the solver using function solve or by constructor of the class Solver.

`Example`

In the following example, we are using the *TimeLimit* parameter to specify
that the solver should stop after 5 minutes. We also specify that the solver
should use 4 threads. Finally, we specify that the solver should use
*FDS* search (in all threads).

`let params = {`

timeLimit: 300, // In seconds, i.e. 5 minutes

nbWorkers: 4, // Use 4 threads

searchType: "FDS"

};

let result = await CP.solve(myModel, params);

### Worker-specific parameters

Some parameters can be specified differently for each worker. For example,
some workers may use *LNS* search while others use *FDS* search. To specify
worker-specific parameters, use the *workers* parameter and pass an array
of WorkerParameters.

Not all parameters can be specified per worker, for example *TimeLimit* is a
global parameter. See WorkerParameters for the list of parameters
that can be specified per worker.

If a parameter is not set specifically for a worker, the global value is used.

`Example`

In the following example, we are going to use 4 workers, two of them will run
*FDS* search and the remaining two will run *LNS* search. In addition, workers
that use *FDS* search will use increased propagation levels.

`// Parameters for a worker that uses FDS search.`

// FDS works best with increased propagation levels, so set them:

let fdsWorker: CP.WorkerParameters = {

searchType: "FDS",

noOverlapPropagationLevel: 4,

cumulPropagationLevel: 3,

reservoirPropagationLevel: 2

};

// Global parameters:

let params = {

timeLimit: 60, // In seconds, i.e. 1 minute

searchType: "LNS", // The default search type. Not necessary as "LNS" is the default value.

nbWorkers: 4, // Use 4 threads

// The first two workers will use FDS search.

// The remaining two workers will use the defaults, i.e. LNS search with default propagation levels.

workers = [fdsWorker, fdsWorker];

};

let result = await CP.solve(myModel, params);

`See`

- WorkerParameters for worker-specific parameters.
- BenchmarkParameters are an extension of Parameters to simplify benchmarking (e.g. run the same model multiple times with different random seeds).

#### Type declaration

Name | Type | Description |
---|---|---|

`absoluteGapTolerance?` | `number` | Stop the search when gap is below the tolerance. The search is stopped if the absolute difference between the current solution value and current lower/upper bound is not bigger than the specified value. Note that parameters `AbsoluteGapTolerance` and `RelativeGapTolerance` are considered independently, i.e., the search stops if at least one of the conditions apply. The default value is `0` . Takes a floating point value. |

`color?` | `"Never"` | `"Auto"` | `"Always"` | Whether to colorize output to the terminal. This parameter controls when terminal output is colorized. Possible values are: * `never` : don't colorize the output. * `auto` : colorize if the output is a supported terminal. * `always` : always colorize the output. The default value is `Auto` . |

`cumulPropagationLevel?` | `number` | How much to propagate constraints on cumul functions. This parameter controls the amount of propagation done for Model.cumulLe constraint when used with a sum of pulses. The bigger the value, the more algorithms are used for propagation. It means that more time is spent by the propagation, and possibly more values are removed from domains. More propagation doesn't necessarily mean better performance. FDS search (see searchType) usually benefits from higher propagation levels. The default value is `1` . Takes an unsigned integer value in range `1..3` . |

`fdsAdditionalStepRatio?` | `number` | Domain split ratio when run out of choices. When all choices are decided, and a greedy algorithm cannot find a solution, then more choices are generated by splitting domains into the specified number of pieces. The default value is `7` . Takes a floating point value in range `2.000000..Infinity` . |

`fdsBothFailRewardFactor?` | `number` | How much to improve rating when both branches fail immediately. This parameter sets a bonus reward given to a choice when both left and right branches fail immediately. Current rating of both branches is multiplied by the specified value. The default value is `0.98` . Takes a floating point value in range `0..1` . |

`fdsBranchOnObjective?` | `boolean` | Whether to generate choices for objective expression/variable. This option controls the generation of choices on the objective. It works regardless of the objective is given by an expression or a variable. The default value is `false` . |

`fdsEpsilon?` | `number` | How often to chose a choice randomly. Probability that a choice is taken randomly. A randomly selected choice is not added into the search tree automatically. Instead, the choice is tried, its rating is updated, but it is added into the search tree only if one of the branches fails. The mechanism is similar to strong branching. The default value is `0.1` . Takes a floating point value in range `0.000000..0.999990` . |

`fdsEventTimeInfluence?` | `number` | Influence of event time to initial choice rating. When non-zero, then the initial choice rating is influenced by the date of the choice. This way, very first choices in the search should be taken chronologically. The default value is `0` . Takes a floating point value in range `0..1` . |

`fdsFixedAlpha?` | `number` | When non-zero, alpha factor for rating updates. When this parameter is set to a non-zero, then parameter FDSRatingAverageLength is ignored. Instead, the rating of a branch is computed as an exponential moving average with the given parameter alpha. The default value is `0` . Takes a floating point value in range `0..1` . |

`fdsInitialRating?` | `number` | Initial rating for newly created choices. Default rating for newly created choices. Both left and right branches get the same rating. Choice is initially permuted so that bigger domain change is the left branch. The default value is `0.5` . Takes a floating point value in range `0.000000..2.000000` . |

`fdsInitialRestartLimit?` | `number` | Fail limit for the first restart. Failure-directed search is periodically restarted: explored part of the current search tree is turned into a no-good constraint, and the search starts again in the root node. This parameter specifies the size of the very first search tree (measured in number of failures). The default value is `100` . Takes an unsigned integer value in range `1..9223372036854775807` . |

`fdsLBResetRatings?` | `boolean` | Whether to reset ratings when a new LB is proved. When this parameter is on, and FDSLB proves a new lower bound then all ratings are reset to default values. The default value is `false` . |

`fdsLBStrategy?` | `"Minimum"` | `"Random"` | `"Split"` | A strategy to choose objective cuts during FDSLB search.. Possible values are: * `Minimum` : Always change the cut by the minimum amount. The default value. * `Random` : At each restart, randomly choose a value in range LB..UB. * `Split` : Always split the current range LB..UB in half. The default value is `Minimum` . |

`fdsLengthStepRatio?` | `number` | Choice step relative to average length. Ratio of initial choice step size to the minimum length of interval variable.When FDSUniformChoiceStep is set, this ratio is used to compute global choice step using the average of interval var length.When FDSUniformChoiceStep is not set, this ratio is used to compute the choice step for every interval var individually. The default value is `0.699999988079071` . Takes a floating point value in range `0.000000..Infinity` . |

`fdsMaxCounterAfterRestart?` | `number` | Truncate choice use counts after a restart to this value. The idea is that ratings learned in the previous restart are less valid in the new restart. Using this parameter, it is possible to truncate use counts on choices so that new local ratings will have bigger weights (when FDSFixedAlpha is not used). The default value is `255` . Takes an unsigned integer value. |

`fdsMaxCounterAfterSolution?` | `number` | Truncate choice use counts after a solution is found. Similar to `FDSMaxCounterAfterRestart` , this parameter allows truncating use counts on choices when a solution is found. The default value is `255` . Takes an unsigned integer value. |

`fdsMaxInitialChoicesPerVariable?` | `number` | Maximum number of choices generated initially per a variable. Initial domains are often very large (e.g., `0..IntervalMax` ). Therefore initial number of generated choices is limited: only choices near startMin are kept. The default value is `90` . Takes an unsigned integer value in range `2..2147483647` . |

`fdsMaxInitialIntVarChoiceStep?` | `number` | Maximum step when generating initial choices for integer variables.. For a variable with big initial domains, choices are generated only around min value considering the given step. The default value is `107374182` . Takes an unsigned integer value in range `1..1073741823` . |

`fdsPresenceStatusChoices?` | `boolean` | Whether to generate choices on presence status. Choices on start time also include a choice on presence status. Therefore, dedicated choices on presence status only are not mandatory. The default value is `true` . |

`fdsRatingAverageComparison?` | `"Off"` | `"Global"` | `"Depth"` | Whether to compare the local rating with the average. Possible values are: * `Off` (the default): No comparison is done. * `Global` : Compare with the global average. * `Depth` : Compare with the average on the current search depth Arithmetic average is used for global and depth averages. The default value is `Off` . |

`fdsRatingAverageLength?` | `number` | Length of average rating computed for choices. For the computation of rating of a branch. Arithmetic average is used until the branch is taken at least FDSRatingAverageLength times. After that exponential moving average is used with parameter alpha = 1 - 1 / FDSRatingAverageLength. The default value is `25` . Takes an integer value in range `0..254` . |

`fdsReductionFactor?` | `"Normal"` | `"Zero"` | `"Random"` | Reduction factor R for rating computation. Possible values are: * `Normal` (the default): Normal reduction factor. * `Zero` : Factor is not used (it is 0 all the time). * `Random` : A random number in the range [0,1] is used instead. The default value is `Normal` . |

`fdsReductionWeight?` | `number` | Weight of the reduction factor in rating computation. When computing the local rating of a branch, multiply reduction factor by the given weight. The default value is `1` . Takes a floating point value in range `0.000000..Infinity` . |

`fdsResetRestartsAfterSolution?` | `boolean` | Reset restart size after a solution is found (ignored in Luby). When this parameter is set (the default), then restart limit is set back to `FDSInitialRestartLimit` when a solution is found. The default value is `true` . |

`fdsRestartGrowthFactor?` | `number` | Growth factor for fail limit after each restart. After each restart, the fail limit for the restart is multiplied by the specified factor. This parameter is ignored when fdsRestartStrategy is `Luby` . The default value is `1.15` . Takes a floating point value in range `1.000000..Infinity` . |

`fdsRestartStrategy?` | `"Geometric"` | `"Nested"` | `"Luby"` | Restart strategy to use. This parameter specifies how the restart limit (maximum number of failures) changes from restart to restart. Possible values are: * `Geometric` (the default): After each restart, restart limit is multiplied by fdsRestartGrowthFactor. * `Nested` : Similar to `Geometric` but the limit is changed back to fdsInitialRestartLimit each time a new maximum limit is reached. * `Luby` : Luby restart strategy is used. Parameter fdsRestartGrowthFactor is ignored. The default value is `Geometric` . |

`fdsReuseClosing?` | `boolean` | Whether always reuse closing choice. Most of the time, FDS reuses closing choice automatically. This parameter enforces it all the time. The default value is `false` . |

`fdsStrongBranchingCriterion?` | `"Both"` | `"Left"` | `"Right"` | How to choose the best choice in strong branching. Possible values are: * `Both` : Choose the the choice with best combined rating. * `Left` (the default): Choose the choice with the best rating of the left branch. * `Right` : Choose the choice with the best rating of the right branch. The default value is `Left` . |

`fdsStrongBranchingDepth?` | `number` | Up-to what search depth apply strong branching. Strong branching is typically used in the root node. This parameter controls the maximum search depth when strong branching is used. The default value is `6` . Takes an unsigned integer value. |

`fdsStrongBranchingSize?` | `number` | Number of choices to try in strong branching. Strong branching means that instead of taking a choice with the best rating, we take the specified number (FDSStrongBranchingSize) of best choices, try them in dry-run mode, measure their local rating, and then chose the one with the best local rating. The default value is `10` . Takes an unsigned integer value. |

`fdsUniformChoiceStep?` | `boolean` | Whether all initial choices have the same step length. When set then initial choices generated on interval variables have all the same step size. The default value is `true` . |

`fdsUseNogoods?` | `boolean` | Whether to use or not nogood constraints. By default, no-good constraint is generated after each restart. This parameter allows to turn no-good constraints off. The default value is `true` . |

`infoTraceLevel?` | `number` | Level of information trace. This parameter is available only in the development edition of the solver. When set to a value bigger than zero, the solver prints various high-level information. The higher the value, the more information is printed. The default value is `0` . Takes an unsigned integer value in range `0..5` . |

`logLevel?` | `number` | Level of the log. This parameter controls the amount of text the solver writes on standard output. The solver is completely silent when this option is set to 0. The default value is `2` . Takes an unsigned integer value in range `0..3` . |

`logPeriod?` | `number` | How often to print log messages (in seconds). When logLevel ≥ 2 then solver writes a log message every `logPeriod` seconds. The log message contains the current statistics about the solve: number of branches, number of fails, memory used, etc. The default value is `2` . Takes a floating point value in range `0.010000..Infinity` . |

`nbWorkers?` | `number` | Number of threads dedicated to search. When this parameter is 0 (the default), the number of workers is determined the following way: * If environment variable `OPTALCP_NB_WORKERS` is set, its value is used. * Otherwise, all available cores are used. The default value is `0` . Takes an unsigned integer value. |

`noOverlapPropagationLevel?` | `number` | How much to propagate noOverlap constraints. This parameter controls the amount of propagation done for noOverlap constraints. The bigger the value, the more algorithms are used for propagation. It means that more time is spent by the propagation, and possibly more values are removed from domains. More propagation doesn't necessarily mean better performance. FDS search (see searchType) usually benefits from higher propagation levels. The default value is `2` . Takes an unsigned integer value in range `1..4` . |

`propagationTraceLevel?` | `number` | Level of propagation trace. This parameter is available only in the development edition of the solver. When set to a value bigger than zero, the solver prints a trace of the propagation, that is a line for every domain change. The higher the value, the more information is printed. The default value is `0` . Takes an unsigned integer value in range `0..5` . |

`randomSeed?` | `number` | Random seed. The solver breaks ties randomly using a pseudorandom number generator. This parameter sets the seed of the generator. Note that when Parameters.nbWorkers is more than 1 then there is also another source of randomness: the time it takes for a message to pass from one worker to another. Therefore with Parameters.nbWorkers=1 the solver is deterministic (random behavior depends only on random seed). With Parameters.nbWorkers>1 the solver is not deterministic. Even with NbSeeds=1 and the same random seed, the solver may behave differently on different platforms. This can be due to different implementations of certain functions such as `std::sort` . The default value is `1` . Takes an unsigned integer value. |

`relativeGapTolerance?` | `number` | Stop the search when gap is below the tolerance. The search is stopped if the relative difference between the current solution value and current lower/upper bound is not bigger than the specified value. Note that parameters `AbsoluteGapTolerance` and `RelativeGapTolerance` are considered independently, i.e., the search stops if at least one of the conditions apply. The default value is `0.0001` . Takes a floating point value. |

`reservoirPropagationLevel?` | `number` | How much to propagate constraints on cumul functions. This parameter controls the amount of propagation done for Model.cumulLe and Model.cumulGe when used together with steps (Model.stepAtStart, Model.stepAtEnd, Model.stepAt). The bigger the value, the more algorithms are used for propagation. It means that more time is spent by the propagation, and possibly more values are removed from domains. More propagation doesn't necessarily mean better performance. FDS search (see searchType) usually benefits from higher propagation levels. The default value is `1` . Takes an unsigned integer value in range `1..2` . |

`searchTraceLevel?` | `number` | Level of search trace. This parameter is available only in the development edition of the solver. When set to a value bigger than zero, the solver prints a trace of the search. The trace contains information about every choice taken by the solver. The higher the value, the more information is printed. The default value is `0` . Takes an unsigned integer value in range `0..5` . |

`searchType?` | `"LNS"` | `"FDS"` | `"FDSLB"` | `"SetTimes"` | Type of search to use. Possible values are: * `LNS` : Large Neighborhood Search * `FDS` : Failure-Directed Search * `FDSLB` : Failure-Directed Searching working on lower bound * `SetTimes` : Depth-first set-times search (not restarted) The default value is `LNS` . |

`simpleLBMaxIterations?` | `number` | Maximum number of feasibility checks. Simple lower bound is computed by binary search for the best objective value that is not infeasible by propagation. This parameter limits the maximum number of iterations of the binary search. The default value is `2147483647` . Takes an unsigned integer value in range `1..2147483647` . |

`simpleLBShavingRounds?` | `number` | Number of shaving rounds. When non-zero, the solver will use shaving on variable domains to improve the lower bound. This parameter controls the number of shaving rounds. The default value is `0` . Takes an unsigned integer value in range `0..2147483647` . |

`simpleLBWorker?` | `number` | Which worker computes simple lower bound. Simple lower bound is a bound such that infeasibility of a better objective can be proved by propagation only (without the search). Simple lower bound is computed by the given worker before its start normal search. If worker with the given number doesn't exist then the lower bound is not computed. The default value is `0` . Takes an integer value in range `-1..2147483647` . |

`solutionLimit?` | `number` | Stop the search after the given number of solutions. blah blah blah The default value is `18446744073709551615` . Takes an unsigned integer value. |

`solverPath?` | `string` | - |

`stepFunctionSumPropagationLevel?` | `number` | How much to propagate stepFunctionSum expression. This parameter controls the amount of propagation done for Model.stepFunctionSum expressions. In particular, it controls whether the propagation also affects the minimum and the maximum length of the associated interval variable: * `1` : The length is updated only once during initial constraint propagation. * `2` : The length is updated every time the expression is propagated. The default value is `1` . Takes an unsigned integer value in range `1..2` . |

`timeLimit?` | `number` | Wall clock limit for execution. blah blah blah The default value is `Infinity` . Takes a floating point value in range `0.000000..Infinity` . |

`usePrecedenceEnergy?` | `number` | Whether to use precedence energy propagation algorithm. Precedence energy algorithm improves propagation of precedence constraints when an interval has multiple predecessors (or successors). which use the same resource (noOverlap or cumulative constraint). In this case, the predecessors (or successors) may be in disjunction. Precedence energy algorithm can leverage this information and propagate the precedence constraint more aggressively. The default value is `0` . Takes an unsigned integer value in range `0..1` . |

`verifySolutions?` | `boolean` | When on, the correctness of solutions is verified. Verification is an independent algorithm that checks whether all constraints in the model are satisfied (or absent), and that objective value was computed correctly. Verification is a somewhat redundant process as all solutions should be correct. Its purpose is to double-check and detect bugs in the solver. The default value is `false` . |

`warningLevel?` | `number` | Level of warnings. This parameter controls the types of warnings the solver emits. When this parameter is set to 0 then no warnings are emitted. blah blah blah The default value is `2` . Takes an unsigned integer value in range `0..3` . |

`workers?` | `WorkerParameters` [] | - |

### WorkerParameters

Ƭ **WorkerParameters**: `Object`

WorkerParameters allow to specify how each individual worker of the solver should behave. It is part of the Parameters object.

If a parameter is not listed here then it can be set only globally (in Parameters}), not per worker. For example *timeLimit* or *logPeriod* are
global parameters.

#### Type declaration

Name | Type | Description |
---|---|---|

`cumulPropagationLevel?` | `number` | How much to propagate constraints on cumul functions. This parameter controls the amount of propagation done for Model.cumulLe constraint when used with a sum of pulses. The bigger the value, the more algorithms are used for propagation. It means that more time is spent by the propagation, and possibly more values are removed from domains. More propagation doesn't necessarily mean better performance. FDS search (see searchType) usually benefits from higher propagation levels. The default value is `1` . Takes an unsigned integer value in range `1..3` . |

`fdsAdditionalStepRatio?` | `number` | Domain split ratio when run out of choices. When all choices are decided, and a greedy algorithm cannot find a solution, then more choices are generated by splitting domains into the specified number of pieces. The default value is `7` . Takes a floating point value in range `2.000000..Infinity` . |

`fdsBothFailRewardFactor?` | `number` | How much to improve rating when both branches fail immediately. This parameter sets a bonus reward given to a choice when both left and right branches fail immediately. Current rating of both branches is multiplied by the specified value. The default value is `0.98` . Takes a floating point value in range `0..1` . |

`fdsBranchOnObjective?` | `boolean` | Whether to generate choices for objective expression/variable. This option controls the generation of choices on the objective. It works regardless of the objective is given by an expression or a variable. The default value is `false` . |

`fdsEpsilon?` | `number` | How often to chose a choice randomly. Probability that a choice is taken randomly. A randomly selected choice is not added into the search tree automatically. Instead, the choice is tried, its rating is updated, but it is added into the search tree only if one of the branches fails. The mechanism is similar to strong branching. The default value is `0.1` . Takes a floating point value in range `0.000000..0.999990` . |

`fdsEventTimeInfluence?` | `number` | Influence of event time to initial choice rating. When non-zero, then the initial choice rating is influenced by the date of the choice. This way, very first choices in the search should be taken chronologically. The default value is `0` . Takes a floating point value in range `0..1` . |

`fdsFixedAlpha?` | `number` | When non-zero, alpha factor for rating updates. When this parameter is set to a non-zero, then parameter FDSRatingAverageLength is ignored. Instead, the rating of a branch is computed as an exponential moving average with the given parameter alpha. The default value is `0` . Takes a floating point value in range `0..1` . |

`fdsInitialRating?` | `number` | Initial rating for newly created choices. Default rating for newly created choices. Both left and right branches get the same rating. Choice is initially permuted so that bigger domain change is the left branch. The default value is `0.5` . Takes a floating point value in range `0.000000..2.000000` . |

`fdsInitialRestartLimit?` | `number` | Fail limit for the first restart. Failure-directed search is periodically restarted: explored part of the current search tree is turned into a no-good constraint, and the search starts again in the root node. This parameter specifies the size of the very first search tree (measured in number of failures). The default value is `100` . Takes an unsigned integer value in range `1..9223372036854775807` . |

`fdsLBResetRatings?` | `boolean` | Whether to reset ratings when a new LB is proved. When this parameter is on, and FDSLB proves a new lower bound then all ratings are reset to default values. The default value is `false` . |

`fdsLBStrategy?` | `"Minimum"` | `"Random"` | `"Split"` | A strategy to choose objective cuts during FDSLB search.. Possible values are: * `Minimum` : Always change the cut by the minimum amount. The default value. * `Random` : At each restart, randomly choose a value in range LB..UB. * `Split` : Always split the current range LB..UB in half. The default value is `Minimum` . |

`fdsLengthStepRatio?` | `number` | Choice step relative to average length. Ratio of initial choice step size to the minimum length of interval variable.When FDSUniformChoiceStep is set, this ratio is used to compute global choice step using the average of interval var length.When FDSUniformChoiceStep is not set, this ratio is used to compute the choice step for every interval var individually. The default value is `0.699999988079071` . Takes a floating point value in range `0.000000..Infinity` . |

`fdsMaxCounterAfterRestart?` | `number` | Truncate choice use counts after a restart to this value. The idea is that ratings learned in the previous restart are less valid in the new restart. Using this parameter, it is possible to truncate use counts on choices so that new local ratings will have bigger weights (when FDSFixedAlpha is not used). The default value is `255` . Takes an unsigned integer value. |

`fdsMaxCounterAfterSolution?` | `number` | Truncate choice use counts after a solution is found. Similar to `FDSMaxCounterAfterRestart` , this parameter allows truncating use counts on choices when a solution is found. The default value is `255` . Takes an unsigned integer value. |

`fdsMaxInitialChoicesPerVariable?` | `number` | Maximum number of choices generated initially per a variable. Initial domains are often very large (e.g., `0..IntervalMax` ). Therefore initial number of generated choices is limited: only choices near startMin are kept. The default value is `90` . Takes an unsigned integer value in range `2..2147483647` . |

`fdsMaxInitialIntVarChoiceStep?` | `number` | Maximum step when generating initial choices for integer variables.. For a variable with big initial domains, choices are generated only around min value considering the given step. The default value is `107374182` . Takes an unsigned integer value in range `1..1073741823` . |

`fdsPresenceStatusChoices?` | `boolean` | Whether to generate choices on presence status. Choices on start time also include a choice on presence status. Therefore, dedicated choices on presence status only are not mandatory. The default value is `true` . |

`fdsRatingAverageComparison?` | `"Off"` | `"Global"` | `"Depth"` | Whether to compare the local rating with the average. Possible values are: * `Off` (the default): No comparison is done. * `Global` : Compare with the global average. * `Depth` : Compare with the average on the current search depth Arithmetic average is used for global and depth averages. The default value is `Off` . |

`fdsRatingAverageLength?` | `number` | Length of average rating computed for choices. For the computation of rating of a branch. Arithmetic average is used until the branch is taken at least FDSRatingAverageLength times. After that exponential moving average is used with parameter alpha = 1 - 1 / FDSRatingAverageLength. The default value is `25` . Takes an integer value in range `0..254` . |

`fdsReductionFactor?` | `"Normal"` | `"Zero"` | `"Random"` | Reduction factor R for rating computation. Possible values are: * `Normal` (the default): Normal reduction factor. * `Zero` : Factor is not used (it is 0 all the time). * `Random` : A random number in the range [0,1] is used instead. The default value is `Normal` . |

`fdsReductionWeight?` | `number` | Weight of the reduction factor in rating computation. When computing the local rating of a branch, multiply reduction factor by the given weight. The default value is `1` . Takes a floating point value in range `0.000000..Infinity` . |

`fdsResetRestartsAfterSolution?` | `boolean` | Reset restart size after a solution is found (ignored in Luby). When this parameter is set (the default), then restart limit is set back to `FDSInitialRestartLimit` when a solution is found. The default value is `true` . |

`fdsRestartGrowthFactor?` | `number` | Growth factor for fail limit after each restart. After each restart, the fail limit for the restart is multiplied by the specified factor. This parameter is ignored when fdsRestartStrategy is `Luby` . The default value is `1.15` . Takes a floating point value in range `1.000000..Infinity` . |

`fdsRestartStrategy?` | `"Geometric"` | `"Nested"` | `"Luby"` | Restart strategy to use. This parameter specifies how the restart limit (maximum number of failures) changes from restart to restart. Possible values are: * `Geometric` (the default): After each restart, restart limit is multiplied by fdsRestartGrowthFactor. * `Nested` : Similar to `Geometric` but the limit is changed back to fdsInitialRestartLimit each time a new maximum limit is reached. * `Luby` : Luby restart strategy is used. Parameter fdsRestartGrowthFactor is ignored. The default value is `Geometric` . |

`fdsReuseClosing?` | `boolean` | Whether always reuse closing choice. Most of the time, FDS reuses closing choice automatically. This parameter enforces it all the time. The default value is `false` . |

`fdsStrongBranchingCriterion?` | `"Both"` | `"Left"` | `"Right"` | How to choose the best choice in strong branching. Possible values are: * `Both` : Choose the the choice with best combined rating. * `Left` (the default): Choose the choice with the best rating of the left branch. * `Right` : Choose the choice with the best rating of the right branch. The default value is `Left` . |

`fdsStrongBranchingDepth?` | `number` | Up-to what search depth apply strong branching. Strong branching is typically used in the root node. This parameter controls the maximum search depth when strong branching is used. The default value is `6` . Takes an unsigned integer value. |

`fdsStrongBranchingSize?` | `number` | Number of choices to try in strong branching. Strong branching means that instead of taking a choice with the best rating, we take the specified number (FDSStrongBranchingSize) of best choices, try them in dry-run mode, measure their local rating, and then chose the one with the best local rating. The default value is `10` . Takes an unsigned integer value. |

`fdsUniformChoiceStep?` | `boolean` | Whether all initial choices have the same step length. When set then initial choices generated on interval variables have all the same step size. The default value is `true` . |

`fdsUseNogoods?` | `boolean` | Whether to use or not nogood constraints. By default, no-good constraint is generated after each restart. This parameter allows to turn no-good constraints off. The default value is `true` . |

`noOverlapPropagationLevel?` | `number` | How much to propagate noOverlap constraints. This parameter controls the amount of propagation done for noOverlap constraints. The bigger the value, the more algorithms are used for propagation. It means that more time is spent by the propagation, and possibly more values are removed from domains. More propagation doesn't necessarily mean better performance. FDS search (see searchType) usually benefits from higher propagation levels. The default value is `2` . Takes an unsigned integer value in range `1..4` . |

`propagationTraceLevel?` | `number` | Level of propagation trace. This parameter is available only in the development edition of the solver. When set to a value bigger than zero, the solver prints a trace of the propagation, that is a line for every domain change. The higher the value, the more information is printed. The default value is `0` . Takes an unsigned integer value in range `0..5` . |

`randomSeed?` | `number` | Random seed. The solver breaks ties randomly using a pseudorandom number generator. This parameter sets the seed of the generator. Note that when Parameters.nbWorkers is more than 1 then there is also another source of randomness: the time it takes for a message to pass from one worker to another. Therefore with Parameters.nbWorkers=1 the solver is deterministic (random behavior depends only on random seed). With Parameters.nbWorkers>1 the solver is not deterministic. Even with NbSeeds=1 and the same random seed, the solver may behave differently on different platforms. This can be due to different implementations of certain functions such as `std::sort` . The default value is `1` . Takes an unsigned integer value. |

`reservoirPropagationLevel?` | `number` | How much to propagate constraints on cumul functions. This parameter controls the amount of propagation done for Model.cumulLe and Model.cumulGe when used together with steps (Model.stepAtStart, Model.stepAtEnd, Model.stepAt). The bigger the value, the more algorithms are used for propagation. It means that more time is spent by the propagation, and possibly more values are removed from domains. More propagation doesn't necessarily mean better performance. FDS search (see searchType) usually benefits from higher propagation levels. The default value is `1` . Takes an unsigned integer value in range `1..2` . |

`searchTraceLevel?` | `number` | Level of search trace. This parameter is available only in the development edition of the solver. When set to a value bigger than zero, the solver prints a trace of the search. The trace contains information about every choice taken by the solver. The higher the value, the more information is printed. The default value is `0` . Takes an unsigned integer value in range `0..5` . |

`searchType?` | `"LNS"` | `"FDS"` | `"FDSLB"` | `"SetTimes"` | Type of search to use. Possible values are: * `LNS` : Large Neighborhood Search * `FDS` : Failure-Directed Search * `FDSLB` : Failure-Directed Searching working on lower bound * `SetTimes` : Depth-first set-times search (not restarted) The default value is `LNS` . |

`simpleLBMaxIterations?` | `number` | Maximum number of feasibility checks. Simple lower bound is computed by binary search for the best objective value that is not infeasible by propagation. This parameter limits the maximum number of iterations of the binary search. The default value is `2147483647` . Takes an unsigned integer value in range `1..2147483647` . |

`simpleLBShavingRounds?` | `number` | Number of shaving rounds. When non-zero, the solver will use shaving on variable domains to improve the lower bound. This parameter controls the number of shaving rounds. The default value is `0` . Takes an unsigned integer value in range `0..2147483647` . |

`simpleLBWorker?` | `number` | Which worker computes simple lower bound. Simple lower bound is a bound such that infeasibility of a better objective can be proved by propagation only (without the search). Simple lower bound is computed by the given worker before its start normal search. If worker with the given number doesn't exist then the lower bound is not computed. The default value is `0` . Takes an integer value in range `-1..2147483647` . |

`stepFunctionSumPropagationLevel?` | `number` | How much to propagate stepFunctionSum expression. This parameter controls the amount of propagation done for Model.stepFunctionSum expressions. In particular, it controls whether the propagation also affects the minimum and the maximum length of the associated interval variable: * `1` : The length is updated only once during initial constraint propagation. * `2` : The length is updated every time the expression is propagated. The default value is `1` . Takes an unsigned integer value in range `1..2` . |

### copyParameters

▸ **copyParameters**(`params`

): `Parameters`

This function creates a deep copy of the input Parameters object. It could be used to copy the parameters and modify them without affecting the original Parameters object.

#### Parameters

Name | Type | Description |
---|---|---|

`params` | `Parameters` | The Parameters object to copy. |

#### Returns

A deep copy of the input Parameters object.

### parseParameters

▸ **parseParameters**(`params?`

, `usage?`

, `args?`

): `Parameters`

Parses command-line solver parameters and returns a Parameters object.

#### Parameters

Name | Type | Description |
---|---|---|

`params` | `Parameters` | The default parameters. The function will overwrite the parameters with values specified on the command line. |

`usage?` | `string` | A string that describes how to use the application. It is printed when `--help` or `-h` is given. |

`args` | `string` [] | The command-line arguments to parse. If not specified then `process.argv.slice(2)` is used. |

#### Returns

`Remarks`

For a command-line oriented application, it is useful to specify solver parameters using command-line arguments. This function parses command-line arguments and returns a Parameters object.

Parameter *params* is input/output. It may contain default setting that will
be overwritten during parsing.

In case of an error (e.g.
unrecognized parameter or an invalid parameter value) the function prints the
error an calls `process.exit(1)`

.

If `--help`

or `-h`

is given then the function prints help and calls
`process.exit(0)`

. The printed help is created by concatenating the provided
`usage`

, then follows the list of recognized parameters which looks like this:

`Solver path:`

--solverPath string Path to the solver

Terminal output:

--color Never|Auto|Always Whether to colorize output to the terminal

Major options:

--nbWorkers uint32 Number of threads dedicated to search

--searchType LNS|FDS|FDSLB|SetTimes

Type of search to use

--randomSeed uint32 Random seed

--logLevel uint32 Level of the log

--warningLevel uint32 Level of warnings

--logPeriod double How often to print log messages (in seconds)

--verifySolutions bool When on, correctness of solutions is verified

Limits:

--timeLimit double Wall clock limit for execution

--solutionLimit uint64 Stop the search after the given number of solutions

...

WorkerParameters can be specified for individual workers using `--workerN.`

prefix.
For example, `--worker0.searchType FDS`

sets the search type for the first worker only.

`See`

- This function does not accept any unrecognized arguments. See function parseSomeParameters if you want to allow unrecognized arguments and parse them later.
- See parseBenchmarkParameters and parseSomeBenchmarkParameters for functions that parse BenchmarkParameters.

### parseSomeParameters

▸ **parseSomeParameters**(`params`

, `usage?`

, `args?`

): `string`

[]

Parses command-line solver parameters and returns array of unrecognized arguments.

#### Parameters

Name | Type | Description |
---|---|---|

`params` | `Parameters` | The input/output object. The function will overwrite the parameters with values specified on the command line. |

`usage?` | `string` | A string that describes how to use the application. It is printed when `--help` or `-h` is given. |

`args` | `string` [] | The command-line arguments to parse. If not specified then `process.argv.slice(2)` is used. |

#### Returns

`string`

[]

An array of unrecognized arguments.

`Remarks`

For a command-line oriented application, it is useful to specify solver parameters
using command-line arguments. This function parses command-line arguments and
modifies the input *params* object accordingly. It returns an array of
unrecognized arguments that were not parsed.

The function is similar to parseParameters but it does not stop
if an unrecognized parameter is encountered. Instead, it returns an array of
unrecognized arguments. The caller can then decide what to do with them.
The function can still call `process.exit(1)`

if another type of error is
encountered.

The parameter `params`

is input/output. It may contain default setting that
will be overwritten during parsing.

If `--help`

or `-h`

is given then the function prints help and calls
`process.exit(0)`

. The printed help is created by concatenating the provided
*usage*, then follows the list of recognized parameters which looks like this:

`Solver path:`

--solverPath string Path to the solver

Terminal output:

--color Never|Auto|Always Whether to colorize output to the terminal

Major options:

--nbWorkers uint32 Number of threads dedicated to search

--searchType LNS|FDS|FDSLB|SetTimes

Type of search to use

--randomSeed uint32 Random seed

--logLevel uint32 Level of the log

--warningLevel uint32 Level of warnings

--logPeriod double How often to print log messages (in seconds)

--verifySolutions bool When on, correctness of solutions is verified

Limits:

--timeLimit double Wall clock limit for execution

--solutionLimit uint64 Stop the search after the given number of solutions

...

WorkerParameters can be specified for individual workers using `--workerN.`

prefix.
For example, `--worker0.searchType FDS`

sets the search type for the first worker only.

`See`

- parseParameters for a similar function that don't accept unrecognized arguments.
- functions parseBenchmarkParameters and parseSomeBenchmarkParameters for for parsing BenchmarkParameters.

## Solving

### LowerBoundEvent

Ƭ **LowerBoundEvent**: `Object`

An event that is emitted by Solver when a new (i.e. better) lower bound of the objective is found.

The event can be intercepted by calling
Solver.on("lower bound", ...) with `"lowerBound"`

event name.
The event contains the new lower bound and the solving time so far.

`See`

#### Type declaration

Name | Type | Description |
---|---|---|

`solveTime` | `number` | Duration of the solve at the time the lower bound was found, in seconds. |

`value` | `ObjectiveValue` | The new lower bound of the objective. |

### ObjectiveHistoryItem

Ƭ **ObjectiveHistoryItem**: `Object`

An item in SolveResult.objectiveHistory array. There is one item for each solution found.

#### Type declaration

Name | Type | Description |
---|---|---|

`objective` | `ObjectiveValue` | Objective value of the solution. |

`solveTime` | `number` | Duration of the solve at the time the solution was found, in seconds. |

`valid?` | `true` | Result of the verification of the solution. When parameter Parameters.verifySolutions is set to true (the default), then the solver verifies all solutions found. The verification checks that all constraints in the model are satisfied and that the objective value is computed correctly. The verification is done by a separate code that is not used during the search. The point is to verify independently the correctness of the solution. Possible values are: * `undefined` - the solution was not verified (because the parameter Parameters.verifySolutions was not set). * `true` - the solution was verified and it is correct. The value can never be `false` because in this case the solver would stop with an error. |

### ObjectiveValue

Ƭ **ObjectiveValue**: `undefined`

| `number`

| `null`

| (`number`

| `null`

)[]

Objective value of the solution. Model can specify an objective to Model.minimize or Model.maximize. When a solution is found, the value of the objective is stored in this object.

If the model did not specify an objective then *ObjectiveValue* is undefined.
Objective value is *absent* (see optional IntExpr) is
translated into JavaScript *null*.

In case of multi-objective optimization (not implemented), this object contains an array of individual objective values.

`See`

### SolutionEvent

Ƭ **SolutionEvent**: `Object`

An event that is emitted by Solver when a solution is found.

The event can be intercepted by calling Solver.on('solution', ...). The event contains the solution, solving time so far and the result of solution verification.

`See`

#### Type declaration

Name | Type | Description |
---|---|---|

`solution` | `Solution` | Solution of the model. The solution contains values of all variables in the model (including optional variables) and the value of the objective (if the model specified one). Note that in evaluation version of OptalCP the values of variables in the solution are masked and replaced by value absent (`null` in JavaScript). |

`solveTime` | `number` | Duration of the solve at the time the solution was found, in seconds. |

`valid?` | `true` | Result of the verification of the solution. When parameter Parameters.verifySolutions is set to true (the default), then the solver verifies all solutions found. The verification checks that all constraints in the model are satisfied and that the objective value is computed correctly. The verification is done by a separate code that is not used during the search. The point is to verify independently the correctness of the solution. Possible values are: * `undefined` - the solution was not verified (because the parameter Parameters.verifySolutions was not set). * `true` - the solution was verified and it is correct. The value can never be `false` because in that case the solver ends with an error. |

### SolveResult

Ƭ **SolveResult**: `SolveSummary`

& { `bestLBTime?`

: `number`

; `bestSolution?`

: `Solution`

; `bestSolutionTime?`

: `number`

; `bestSolutionValid?`

: `true`

; `lowerBoundHistory`

: `LowerBoundEvent`

[] ; `objectiveHistory`

: `ObjectiveHistoryItem`

[] }

The result of function solve. It contains all information from SolveSummary such as the best solution found and some statistics about the search. In addition, it contains the best solution found, the history of the objective values etc.

### SolveSummary

Ƭ **SolveSummary**: `Object`

A value emitted by Solver as `summary`

event at the end of the
solve.
The information includes the number of solutions found, the total duration
of the solve, the number of branches, fails, propagations, restarts, etc.

`See`

#### Type declaration

Name | Type | Description |
---|---|---|

`cpu` | `string` | The CPU name detected by the solver. A string such as `"AMD Ryzen 9 5950X"` . |

`duration` | `number` | The total duration of the solve (measured by the server). |

`lowerBound?` | `ObjectiveValue` | Lower bound of the objective: the solver proved that there isn't any solution with a better objective value than the lower bound. If no such bound was proved then `undefined` . |

`memoryUsed` | `number` | Memory used during the solve (in bytes). |

`nbBranches` | `number` | The total number of branches during the solve. |

`nbConstraints` | `number` | The total number of constraints in the input model. |

`nbFails` | `number` | The total number of fails during the solve. |

`nbIntervalVars` | `number` | The total number of interval variables in the input model. |

`nbLNSSteps` | `number` | The total number of propagations during the solve. |

`nbRestarts` | `number` | The total number of restarts during the solve. |

`nbSolutions` | `number` | Number of solutions found during the solve. |

`nbWorkers` | `number` | Number of workers (CPU threads) used during the solve. |

`objective?` | `ObjectiveValue` | Objective value of the best solution found. If no solution was found then `undefined` . |

`objectiveSense` | `"minimize"` | `"maximize"` | `undefined` | Whether the objective was to minimize, maximize or no objective was given. |

`proof` | `boolean` | Whether the solve ended by a proof (of optimality or infeasibility). |

`solver` | `string` | The solver used for solving. A string such as `"OptalCP 1.0.0"` . |

### solve

▸ **solve**(`model`

, `params?`

, `warmStart?`

, `log?`

): `Promise`

<`SolveResult`

>

Solve the provided model and return the result.

#### Parameters

Name | Type | Description |
---|---|---|

`model` | `Model` | The model to solve. |

`params?` | `Parameters` | The parameters to use for solving. |

`warmStart?` | `Solution` | The solution to start with. |

`log?` | `null` | `WritableStream` | The stream to which the solver output (log, trace and warnings) should be redirected. When undefined then the output is printed on standard output. When null then the output is suppressed. |

#### Returns

`Promise`

<`SolveResult`

>

The result of the solve.

`Remarks`

This function is asynchronous and returns a promise. Use e.g. `await`

to wait
for the result. When an error occurs then the returned promise is rejected
and standard `Error`

object is returned.

If `warmStart`

parameter is specified then the solver will start with the
given solution. The solution must be compatible with the model otherwise
an error is raised. The solver will take advantage of the
solution to speed up the search: it will search only for better solutions
(if it is a minimization or maximization problem). The solver may also try to
improve the provided solution by Large Neighborhood Search.

To communicate asynchronously with the solver use class Solver instead. E.g. to process every solution found, or to send external solutions to the solver

For an example of using this function see Model.

## Benchmarking

### BaseBenchmarkResult

Ƭ **BaseBenchmarkResult**: `Object`

Basic data about a benchmark run results produced by function benchmark. The following properties are always present in BenchmarkResult, regardless whether the benchmark was successful or ended by an error.

`See`

#### Type declaration

Name | Type | Description |
---|---|---|

`modelName` | `string` | Name of the model that was run. See Model.setName. |

`parameters` | `Parameters` | Parameters used to solve the model. Those parameters are the same as passed to function benchmark, except for parameter Parameters.randomSeed that can be changed when BenchmarkParameters.nbSeeds is used. |

`solveDate` | `Date` | The date when the model was solved. |

### BenchmarkParameters

Ƭ **BenchmarkParameters**: `Parameters`

& { `dontOutputSolutions?`

: `boolean`

; `exportDomains?`

: `string`

; `exportJS?`

: `string`

; `exportJSON?`

: `string`

; `exportTxt?`

: `string`

; `log?`

: `string`

; `maxObjective?`

: `number`

; `minObjective?`

: `number`

; `nbParallelRuns?`

: `number`

; `nbSeeds?`

: `number`

; `output?`

: `string`

; `result?`

: `string`

; `solve?`

: `boolean`

; `summary?`

: `string`

}

Extension of Parameters that can be used to parameterize function benchmark.

The parameters are the same as in Parameters with some additions that control the behavior of function benchmark. In particular, there are parameters that allow to store the output in file(s), run the model multiple times with multiple seeds, etc.

Parameters can be also parsed from command line arguments using function parseBenchmarkParameters or parseSomeBenchmarkParameters.

### Filename patterns

Some parameters can specify a filename pattern. Patterns allows to generate a unique file name for each benchmark run. The pattern is a string that can contain the following placeholders:

`{name}`

- the name of the model (see Model.setName). If the model name is not set (it is`undefined`

) then a unique name is generated.`{seed}`

- the seed used for the run. Useful especially in combination with`nbSeeds`

parameter.`{flat_name}`

- the name of the model with all characters`'/'`

replaced by`'_'`

.

### BenchmarkResult

Ƭ **BenchmarkResult**: `ErrorBenchmarkResult`

| `NormalBenchmarkResult`

Data about a benchmark run produced by function benchmark.

When the run ended by an error then `error`

property is a string describing
the error and the result is of type ErrorBenchmarkResult.
Otherwise `error`

property is `undefined`

and the result is of type
NormalBenchmarkResult.

Regardless whether the run ended by an error or not, the result contains properties from BaseBenchmarkResult with basic information about the run (model name, solve date and parameters used).

`See`

### ErrorBenchmarkResult

Ƭ **ErrorBenchmarkResult**: `BaseBenchmarkResult`

& { `error`

: `string`

}

Data about a benchmark run that ended by an error (see function benchmark).

It is an extension of BaseBenchmarkResult with additional property `error`

that describes the error.

`See`

### NormalBenchmarkResult

Ƭ **NormalBenchmarkResult**: `BaseBenchmarkResult`

& `SolveResult`

& { `error`

: `undefined`

}

Data about normal benchmark run (that didn't end aby an error), see function benchmark.

It is an extension of BaseBenchmarkResult
and SolveResult, i.e. it contains all properties from those two types.
In addition it contains `error`

field that is always `undefined`

.

`See`

### ProblemGenerator

Ƭ **ProblemGenerator**: (`input`

: `any`

) => `ProblemDefinition`

| `Model`

| `Promise`

<`ProblemDefinition`

> | `Promise`

<`Model`

>

A function that generates a problem definition or a model from the given input. The function can be `async`

.

#### Type declaration

▸ (`input`

): `ProblemDefinition`

| `Model`

| `Promise`

<`ProblemDefinition`

> | `Promise`

<`Model`

>

##### Parameters

Name | Type |
---|---|

`input` | `any` |

##### Returns

`ProblemDefinition`

| `Model`

| `Promise`

<`ProblemDefinition`

> | `Promise`

<`Model`

>

### benchmark

▸ **benchmark**(`problemGenerator`

, `inputs`

, `params`

): `Promise`

<`BenchmarkResult`

[]>

Benchmark given model or a set of models.

#### Parameters

Name | Type | Description |
---|---|---|

`problemGenerator` | `ProblemGenerator` | A function that takes an input and returns a ProblemDefinition or a Model. The function will be called for each input in the array `inputs` . |

`inputs` | `any` [] | An array of inputs to the problem generator. |

`params` | `BenchmarkParameters` | Benchmark parameters to use (it includes Parameters of the solver). |

#### Returns

`Promise`

<`BenchmarkResult`

[]>

An array of results, one for each run.

`Remarks`

This function is used to run benchmarks of the solver. It can be used to solve a single model or multiple models. The models can be generated from data files, or they can be generated on the fly. The function can also export the models into JSON, JavaScript or text formats.

The function will call the given `problemGenerator`

for each input in the
array `inputs`

. The input can be anything, it is up to the problem generator
to interpret it (it could be e.g. a name of a data file). The problem
generator should return either a Model or a ProblemDefinition
(a model with parameters and warm start). Then the function will solve the
model and return an array of results.

Using BenchmarkParameters it is possible to specify additional parameters of the benchmark. For example:

- Each problem can be solved multiple times with different random random seeds (using parameter BenchmarkParameters.nbSeeds). This is useful to get more reliable statistics about the problem performance.
- Multiple models can be solved in parallel to speed up the computation (using parameter BenchmarkParameters.nbParallelRuns | BenchmarkParameters.nbParallelRuns). In this case it is useful to limit the number of threads for each solve by parameter Parameters.nbWorkers.
- The function can also output the results in CSV or JSON formats or export the models into JSON, JavaScript or text formats.

See BenchmarkParameters for more details.

If multiple models are solved (or one model with multiple seeds), this function suppresses the normal output and instead it prints a table with statistics of the runs. The table is printed on the standard output.

If the array `inputs`

is empty then the function writes an error message
to the standard output and terminates the program with exit code 1.

In case of an error during solve, the function does not throw an exception but returns ErrorBenchmarkResult for the given run.

As BenchmarkParameters are an extension of Parameters,
the parameter `params`

can be used to overwrite parameters for all solves.
If `problemGenerator`

returns a ProblemDefinition, then the
parameters from the problem definition are used as a base and the parameters
from `params`

are used to overwrite them (using combineParameters).

`Example`

Let's suppose that we have a function `createModel`

that takes a filename as
a parameter and returns Model. For example, the function can model
jobshop problem and read the data from a file.

We are going to create a command line application around `createModel`

that allows to solve multiple models, using multiple random seeds,
run benchmarks in parallel, store results in files etc.

`import * as CP from '@scheduleopt/optalcp';`

function createModel(filename: string): CP.Model {

...

}

// What to print when --help is specified (assuming that the program name is benchmark.js):

let usage = "Usage: node mybenchmark.js [options] <datafile1> [<datafile2> ...";

// Unless specified differently on the command line, time limit will be 60s:

let params = CP.BenchmarkParameters = { timeLimit: 60 }

// Parse command line arguments, unrecognized arguments are assumed to be file names:

let filenames = CP.parseSomeBenchmarkParameters(params, usage);

// And run the benchmark. The benchmark will call createModel for each file in filenames.

CP.benchmark(createModel, filenames, params);

The resulting program can be used for example as follows:

`node mybenchmark.js --nbParallelRuns 2 --nbWorkers 2 --worker0.noOverlapPropagationLevel 4 \`

--output results.json --summary summary.csv --log `logs/{name}.txt` \

data/*.txt

In this case the program will solve all benchmarks from the directory `data`

, running
two solves in parallel, each with two workers (threads). The first worker will use
propagation level 4 for the Model.noOverlap constraint. The results will be
stored in JSON file `results.json`

(an array of BenchmarkResult objects),
a summary will be stored in CSV file `summary.csv`

, and the log files for individual
runs will be stored in the directory `logs`

(one file for each run named
after the model, see Model.setName.

### parseBenchmarkParameters

▸ **parseBenchmarkParameters**(`params?`

, `usage?`

, `args?`

): `BenchmarkParameters`

Parse benchmark parameters from command line arguments.

#### Parameters

Name | Type | Description |
---|---|---|

`params` | `BenchmarkParameters` | Input/output argument. Contains default values of parameters that will be overridden by command line arguments. When not specified, empty object `{}` is used. |

`usage?` | `string` | Usage string that will be printed when `-h` or `--help` is specified on the command line. The specified `usage` is followed by description of supported benchmark and solver parameters. |

`args` | `string` [] | Command line arguments to parse. When not specified, `process.argv.slice(2)` is used. |

#### Returns

`Remarks`

This function parses command line arguments. In case of an error
it prints an error message and terminates the program. The default
parameters can be specified using parameter `params`

.

When `--help`

or `-h`

is specified then the function prints the `usage`

string followed by description of supported benchmark and engine parameters,
and then terminates the program.

The description of supported parameters looks like this:

`Benchmarking options:`

--nbSeeds uint32 Test models on given number of random seeds

--nbParallelRuns uint32 Run given number of solves in parallel

--minObjective double Require given minimum objective value

--maxObjective double Require given maximum objective value

--dontSolve Not really solve. Useful e.g. with --exportJSON

Overall benchmarking output:

--output fileName Write detailed results of all runs into a JSON file

--summary fileName Write summary table of all runs into a CSV file

--dontOutputSolutions Do not write solutions into the output file (save space)

Outputs for individual benchmarking runs:

--result fileNamePattern Write detailed result into JSON file

--log fileNamePattern Write log into specified text file

--exportJSON fileNamePattern Export problem into a JSON file

--exportTxt fileNamePattern Export problem into a text file

--exportDomains fileNamePattern Export domains after propagate into a text file

Where fileNamePattern undergo the following expansion:

{name} -> Model name (by convention name of the source data file)

{flat_name} -> Like {name} but all characters '/' is replaced by '_'

{seed} -> Random seed

Solver path:

--solverPath string Path to the solver

Terminal output:

--color Never|Auto|Always Whether to colorize output to the terminal

Major options:

--nbWorkers uint32 Number of threads dedicated to search

--searchType LNS|FDS|FDSLB|SetTimes

Type of search to use

--randomSeed uint32 Random seed

--logLevel uint32 Level of the log

--warningLevel uint32 Level of warnings

--logPeriod double How often to print log messages (in seconds)

--verifySolutions bool When on, correctness of solutions is verified

...

WorkerParameters can be specified for individual workers using `--workerN.`

prefix,
and also for worker ranges using `--workerN-M.`

prefix.
For example:

`--worker0.searchType FDS`

sets the search type for the first worker only.`--worker4-8.noOverlapPropagationLevel 4`

sets propagation level of`noOverlap`

constraint for workers 4, 5, 6, 7 and 8.

`See`

- parseSomeBenchmarkParameters for a version that allows unrecognized arguments.
- Functions parseParameters and parseSomeParameters for parsing only solver parameters.

### parseSomeBenchmarkParameters

▸ **parseSomeBenchmarkParameters**(`params`

, `usage?`

, `args?`

): `string`

[]

Parses benchmark parameters from command line arguments and returns an array of unrecognized arguments.

#### Parameters

Name | Type | Description |
---|---|---|

`params` | `BenchmarkParameters` | Input/output argument. Contains default values of parameters that will be overridden by command line arguments. |

`usage?` | `string` | Usage string that will be printed when `-h` or `--help` is specified on the command line. The specified `usage` is followed by description of supported benchmark and solver parameters. |

`args` | `string` [] | Command line arguments to parse. When not specified, `process.argv.slice(2)` is used. |

#### Returns

`string`

[]

An array of unrecognized arguments.

Functionally, this function is the same as parseBenchmarkParameters, however does not exit the application in case of an unrecognized argument. Instead it returns an array of unrecognized arguments.

`See`

- parseBenchmarkParameters for more details.
- parseParameters, parseSomeParameters for parsing only solver parameters.

## Propagation

### PropagationResult

Ƭ **PropagationResult**: `Object`

Result of constraint propagation (see propagate).

This object contains the result of constraint propagation: variable domains, duration of the propagation, number of variables etc.

The propagation can also recognize that the model is infeasible. In this case
the property PropagationResult.domains is set to `"infeasible"`

.
The propagation can also finish by a limit, in this case PropagationResult.domains is
set to "limit".

#### Type declaration

Name | Type | Description |
---|---|---|

`domains` | `"infeasible"` | `"limit"` | `ModelDomains` | Variable domains after propagation (see ModelDomains). If the model is infeasible then this property is set to `"infeasible"` . If the propagation was stopped because of a limit (in particular time limit) then this property is set to `"limit"` . |

`duration` | `number` | Duration of the propagation in seconds. |

`memoryUsed` | `number` | The amount of memory used by solver for propagation. In bytes. |

`nbConstraints` | `number` | Number of constraints in the input model. |

`nbIntervalVars` | `number` | Number of interval variables in the input model. |

### propagate

▸ **propagate**(`model`

, `parameters?`

, `log?`

): `Promise`

<`PropagationResult`

>

Computes domains after constraint propagation.

#### Parameters

Name | Type | Description |
---|---|---|

`model` | `Model` | The model to propagate. |

`parameters?` | `Parameters` | The parameters to use for propagation. |

`log?` | `null` | `WritableStream` | The stream to which the solver output should be redirected. When `undefined` then the output is printed to the standard output. When `null` then the output is suppressed. |

#### Returns

`Promise`

<`PropagationResult`

>

The result of propagation.

`Remarks`

Propagation removes infeasible values from variable domains. In general, it shrinks the domains but it doesn't fix variables to values. In some cases propagation can prove that the model is infeasible.

Sometimes it may be useful to check what the solver can compute by constraint propagation and what it cannot. For example, if some obviously infeasible values are not removed from variable domains then some redundant constraint can be added.

`Example`

In the following example, we have 4 tasks `task[0]`

, `task[1]`

, `task[2]`

,
`task[3]`

, and 2 workers. Each task can be assigned to any worker and the
tasks can be processed in any order. All tasks have length 10 and must finish
before time 19.

In the first model we will use constraints Model.alternative to chose a worker for each tasks. And we check that constraint propagation correctly propagates the length of the tasks to the workers.

`let model = new CP.Model();`

const nbTasks = 4;

// For each task we will create three interval variables:

// * tasks[i]: the task itself

// * tasksWorker1[i]: the task if executed by worker1

// * tasksWorker2[i]: the task if executed by worker2

let tasks: CP.IntervalVar[] = [];

let tasksWorker1: CP.IntervalVar[] = [];

let tasksWorker2: CP.IntervalVar[] = [];

for (let i = 0; i < nbTasks; i++) {

// Create the task itself. It has length 10 and must finish before 19:

tasks.push(model.intervalVar({ name: "Task" + (i + 1), length: 10, end: [, 19] }));

// Create the variables for workers. Those variables are optional

// since we don't know which worker will execute the task.

// Notice that we don't specify the length of those interval variables.

tasksWorker1.push(model.intervalVar({ name: "Task" + (i + 1) + "Worker1", optional: true }));

tasksWorker2.push(model.intervalVar({ name: "Task" + (i + 1) + "Worker2", optional: true }));

// Alternative constraint between the task and the two worker variables

// makes sure that exactly one of the two workers executes the task:

model.alternative(tasks[i], [tasksWorker1[i], tasksWorker2[i]]);

// All tasks must finish before the time 19:

model.constraint(model.le(tasks[i].end(), 19));

}

// Tasks of each worker cannot overlap:

model.noOverlap(tasksWorker1);

model.noOverlap(tasksWorker2);

try {

// Propagate using the maximum propagation on noOverlap constraint:

let result = await CP.propagate(model, { noOverlapPropagationLevel: 4 });

if (typeof result.domains === "string") {

// The model is infeasible or a timeout occurred:

console.log("The result of the propagation is: " + result.domains);

} else {

// Check computed length of one of the optional tasks:

console.log("Length of Task1Worker1 is: " +

result.domains.getLengthMin(tasksWorker1[0]) + ".." + result.domains.getLengthMax(tasksWorker1[0]));

}

} catch (e) {

// In case of an error CP.propagate returns a rejected promise so an exception is thrown

console.log("Error caught: " + e);

}

The output of the program is:

`Length of Task1Worker1 is: 10..10`

As we can see, the length 10 is correctly propagated from `Task1`

to `Task1Worker1`

.
However propagation did not prove that the model is infeasible: there is no way
to execute four tasks of length 10 before time 19 using only 2 workers.

Let's remodel this problem using a cumulative constraint. The idea is that the workers are interchangeable and we can assign tasks to workers in postprocessing.

`let model = new CP.Model();`

const nbTasks = 4;

// For each task we will create an interval variable

// and also a pulse for cumulative constraint:

let tasks: CP.IntervalVar[] = [];

let pulses: CP.CumulExpr[] = [];

for (let i = 0; i < nbTasks; i++) {

// Create the task. It has length 10 and must finish before 19:

tasks.push(model.intervalVar({ name: "Task" + (i + 1), length: 10, end: [, 19] }));

// And its pulse:

pulses.push(tasks[i].pulse(1));

}

// Cumulative constraint makes sure that we don't use more than 2 workers at a time:

model.cumulSum(pulses).cumulLe(2);

try {

// Propagate using the maximum propagation for cumul constraints:

let result = await CP.propagate(model, { cumulPropagationLevel: 3});

if (typeof result.domains === "string") {

// The model is infeasible or a timeout occurred:

console.log("The result of the propagation is: " + result.domains);

} else

console.log("The propagation did not detect infeasibility.");

} catch (e) {

// In case of an error CP.propagate returns a rejected promise so an exception is thrown

console.log("Error caught: " + e);

}

This time the output is:

`The result of the propagation is: infeasible`

As we can see, this model propagates more then the previous one.

## Model exporting

### ProblemDefinition

Ƭ **ProblemDefinition**: `Object`

The definition of a problem to solve, i.e. all the input the solver needs for solving.

`Remarks`

This type contains everything that is needed to solve a model. In particular it contains the model itself, the parameters to use for solving (optional) and the starting solution (optional).

#### Type declaration

Name | Type | Description |
---|---|---|

`model` | `Model` | The model to solve. |

`parameters?` | `Parameters` | The parameters to use for solving. |

`warmStart?` | `Solution` | The solution to start with. |

### json2problem

▸ **json2problem**(`json`

): `ProblemDefinition`

Converts a problem from JSON format into an instance of ProblemDefinition.

#### Parameters

Name | Type | Description |
---|---|---|

`json` | `string` | A string containing the problem in JSON format. |

#### Returns

An instance of ProblemDefinition corresponding to the model in JSON format.

`Remarks`

It is assumed that the problem was exported using function problem2json.

Variables in the new model can be accessed using function Model.getIntervalVars.

### problem2js

▸ **problem2js**(`model`

, `params?`

, `warmStart?`

, `log?`

): `Promise`

<`string`

| `undefined`

>

Converts a problem into equivalent JavaScript code. The result is human readable.

#### Parameters

Name | Type | Description |
---|---|---|

`model` | `Model` | The model to be exported. |

`params?` | `Parameters` | The parameters to pass to the solver (they are included in the generated code). |

`warmStart?` | `Solution` | An initial solution to start the solver with. |

`log?` | `null` | `WritableStream` | The stream to which the solver output should be redirected. When `undefined` then the output is printed to the standard output. When `null` then the output is suppressed. |

#### Returns

`Promise`

<`string`

| `undefined`

>

A string containing the model in JavaScript format.

`Remarks`

This function is experimental and the result is not guaranteed to be valid.

The result of this function can be stored in a file and executed using Node.js. It is meant as a way to export a model to a format that is executable, human readable, editable and independent of other libraries.

In case of an error this function returns a rejected promise.

### problem2json

▸ **problem2json**(`problem`

): `string`

Translates a problem definition into a JSON format.

#### Parameters

Name | Type | Description |
---|---|---|

`problem` | `ProblemDefinition` | The problem to be exported. |

#### Returns

`string`

A string containing the problem in JSON format.

`Remarks`

The result can be stored in a file, for example. The problem can be converted back from JSON format into an instance of ProblemDefinition using function json2problem.

### problem2txt

▸ **problem2txt**(`model`

, `params?`

, `warmStart?`

, `log?`

): `Promise`

<`string`

| `undefined`

>

Converts a problem into a text format similar to IBM CP Optimizer file format. The result is human readable and can be stored in a file.

#### Parameters

Name | Type | Description |
---|---|---|

`model` | `Model` | The model to be exported. |

`params?` | `Parameters` | The parameters to pass to the solver (they are mostly unused). |

`warmStart?` | `Solution` | An initial solution to start the solver with. |

`log?` | `null` | `WritableStream` | The stream to which the solver output should be redirected. When `undefined` then the output is printed to the standard output. When `null` then the output is suppressed. |

#### Returns

`Promise`

<`string`

| `undefined`

>

A string containing the model in text format.

`Remarks`

Unlike JSON format, there is no way to convert the text format back into an instance of Model.

The result so similar to the file format used by IBM CP Optimizer that, under some circumstances, the result can be used as an input file for CP Optimizer. However there are some differences between OptalCP and CP Optimizer that makes it impossible to make sure the result is always valid for CP Optimizer. Known issues are:

- OptalCP supports optional integer expressions, while CP Optimizer does not. If the model contains optional integer expressions, the result will not be valid for CP Optimizer or it will be badly interpreted. For example, in order to get valid CP Optimizer file, don't use function IntervalVar.start, use IntervalVar.startOr instead.
- For the same reason, prefer precedence constraints such as
Model.endBeforeStart over
`constraint(x.end().le(y.start()))`

. - Negative heights in cumulative expressions (e.g. in Model.stepAtStart) are not supported by CP Optimizer.

The function is using OptalCP solver for the conversion, therefore it is
asynchronous. To wait the result, use `await`

keyword.

In case of an error this function returns a rejected promise.

## Constants

### IntVarMax

• `Const`

**IntVarMax**: `1073741823`

Maximum value of a decision variable or a decision expression (such as `x+1`

where `x`

is a variable).

`Example`

The following model is infeasible:

`let model = new CP.Model();`

let x = model.intVar({range: [10000000, 2000000]});

// Constraint x*x >= 1:

model.constraint(x.times(x).ge(1));

let result = await CP.solve(model);

Because for any value of `x`

, the expression `x*x`

is greater than `IntVarMax`

and thus cannot be computed.

### IntVarMin

• `Const`

**IntVarMin**: `number`

= `-IntVarMax`

Minimum value of a decision variable or a decision expression (such as `x+1`

where `x`

is a variable).
The opposite of IntVarMax.

### IntervalMax

• `Const`

**IntervalMax**: `715827882`

Maximum value of start or end of an interval variable. The opposite of IntervalMin.

### IntervalMin

• `Const`

**IntervalMin**: `-715827882`

Minimum value of start or end of an interval variable. The opposite of IntervalMax.

### LengthMax

• `Const`

**LengthMax**: `number`

Maximum length of an interval variable. The maximum length can be achieved by an interval that starts at IntervalMin and ends at IntervalMax.

### Version

• `Const`

**Version**: `"2024.2.0"`

The version of the module such as "1.0.0".

## Other

### combineParameters

▸ **combineParameters**(`source`

, `modifications`

): `Parameters`

Combines two Parameters settings into a new one.

#### Parameters

Name | Type | Description |
---|---|---|

`source` | `Parameters` | Input parameters that can be modified by `modifications` . |

`modifications` | `Parameters` | Parameters that will overwrite the parameters from `source` . |

#### Returns

`Remarks`

The new object contains all parameters from both inputs. If the same
parameter is specified in both input objects then the value from the second
object `modifications`

is used.

Input objects are not modified.