Skip to main content

@scheduleopt/optalcp

Classes

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

NameTypeDescription
absoluteGapTolerance?numberStop 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?numberHow 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?numberDomain 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?numberHow 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?booleanWhether 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?numberHow 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?numberInfluence 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?numberWhen 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?numberInitial 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?numberFail 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?booleanWhether 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?numberChoice 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?numberTruncate 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?numberTruncate 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?numberMaximum 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?numberMaximum 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?booleanWhether 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?numberLength 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?numberWeight 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?booleanReset 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?numberGrowth 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?booleanWhether 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?numberUp-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?numberNumber 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?booleanWhether 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?booleanWhether 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?numberLevel 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?numberLevel 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?numberHow 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?numberNumber 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?numberHow 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?numberLevel 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?numberRandom 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?numberStop 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?numberHow 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?numberLevel 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?numberMaximum 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?numberNumber 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?numberWhich 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?numberStop the search after the given number of solutions. blah blah blah The default value is 18446744073709551615. Takes an unsigned integer value.
solverPath?string-
stepFunctionSumPropagationLevel?numberHow 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?numberWall clock limit for execution. blah blah blah The default value is Infinity. Takes a floating point value in range 0.000000..Infinity.
usePrecedenceEnergy?numberWhether 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?booleanWhen 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?numberLevel 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

NameTypeDescription
cumulPropagationLevel?numberHow 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?numberDomain 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?numberHow 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?booleanWhether 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?numberHow 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?numberInfluence 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?numberWhen 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?numberInitial 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?numberFail 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?booleanWhether 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?numberChoice 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?numberTruncate 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?numberTruncate 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?numberMaximum 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?numberMaximum 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?booleanWhether 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?numberLength 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?numberWeight 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?booleanReset 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?numberGrowth 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?booleanWhether 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?numberUp-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?numberNumber 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?booleanWhether 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?booleanWhether 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?numberHow 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?numberLevel 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?numberRandom 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?numberHow 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?numberLevel 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?numberMaximum 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?numberNumber 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?numberWhich 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?numberHow 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

NameTypeDescription
paramsParametersThe Parameters object to copy.

Returns

Parameters

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

NameTypeDescription
paramsParametersThe default parameters. The function will overwrite the parameters with values specified on the command line.
usage?stringA string that describes how to use the application. It is printed when --help or -h is given.
argsstring[]The command-line arguments to parse. If not specified then process.argv.slice(2) is used.

Returns

Parameters

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


parseSomeParameters

parseSomeParameters(params, usage?, args?): string[]

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

Parameters

NameTypeDescription
paramsParametersThe input/output object. The function will overwrite the parameters with values specified on the command line.
usage?stringA string that describes how to use the application. It is printed when --help or -h is given.
argsstring[]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

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

NameTypeDescription
solveTimenumberDuration of the solve at the time the lower bound was found, in seconds.
valueObjectiveValueThe 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

NameTypeDescription
objectiveObjectiveValueObjective value of the solution.
solveTimenumberDuration of the solve at the time the solution was found, in seconds.
valid?trueResult 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

NameTypeDescription
solutionSolutionSolution 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).
solveTimenumberDuration of the solve at the time the solution was found, in seconds.
valid?trueResult 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

NameTypeDescription
cpustringThe CPU name detected by the solver. A string such as "AMD Ryzen 9 5950X".
durationnumberThe total duration of the solve (measured by the server).
lowerBound?ObjectiveValueLower 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.
memoryUsednumberMemory used during the solve (in bytes).
nbBranchesnumberThe total number of branches during the solve.
nbConstraintsnumberThe total number of constraints in the input model.
nbFailsnumberThe total number of fails during the solve.
nbIntervalVarsnumberThe total number of interval variables in the input model.
nbLNSStepsnumberThe total number of propagations during the solve.
nbRestartsnumberThe total number of restarts during the solve.
nbSolutionsnumberNumber of solutions found during the solve.
nbWorkersnumberNumber of workers (CPU threads) used during the solve.
objective?ObjectiveValueObjective value of the best solution found. If no solution was found then undefined.
objectiveSense"minimize" | "maximize" | undefinedWhether the objective was to minimize, maximize or no objective was given.
proofbooleanWhether the solve ended by a proof (of optimality or infeasibility).
solverstringThe 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

NameTypeDescription
modelModelThe model to solve.
params?ParametersThe parameters to use for solving.
warmStart?SolutionThe solution to start with.
log?null | WritableStreamThe 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

NameTypeDescription
modelNamestringName of the model that was run. See Model.setName.
parametersParametersParameters 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.
solveDateDateThe 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
NameType
inputany
Returns

ProblemDefinition | Model | Promise<ProblemDefinition> | Promise<Model>


benchmark

benchmark(problemGenerator, inputs, params): Promise<BenchmarkResult[]>

Benchmark given model or a set of models.

Parameters

NameTypeDescription
problemGeneratorProblemGeneratorA function that takes an input and returns a ProblemDefinition or a Model. The function will be called for each input in the array inputs.
inputsany[]An array of inputs to the problem generator.
paramsBenchmarkParametersBenchmark 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

NameTypeDescription
paramsBenchmarkParametersInput/output argument. Contains default values of parameters that will be overridden by command line arguments. When not specified, empty object {} is used.
usage?stringUsage 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.
argsstring[]Command line arguments to parse. When not specified, process.argv.slice(2) is used.

Returns

BenchmarkParameters

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

parseSomeBenchmarkParameters(params, usage?, args?): string[]

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

Parameters

NameTypeDescription
paramsBenchmarkParametersInput/output argument. Contains default values of parameters that will be overridden by command line arguments.
usage?stringUsage 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.
argsstring[]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

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

NameTypeDescription
domains"infeasible" | "limit" | ModelDomainsVariable 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".
durationnumberDuration of the propagation in seconds.
memoryUsednumberThe amount of memory used by solver for propagation. In bytes.
nbConstraintsnumberNumber of constraints in the input model.
nbIntervalVarsnumberNumber of interval variables in the input model.

propagate

propagate(model, parameters?, log?): Promise<PropagationResult>

Computes domains after constraint propagation.

Parameters

NameTypeDescription
modelModelThe model to propagate.
parameters?ParametersThe parameters to use for propagation.
log?null | WritableStreamThe 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

NameTypeDescription
modelModelThe model to solve.
parameters?ParametersThe parameters to use for solving.
warmStart?SolutionThe solution to start with.

json2problem

json2problem(json): ProblemDefinition

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

Parameters

NameTypeDescription
jsonstringA string containing the problem in JSON format.

Returns

ProblemDefinition

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

NameTypeDescription
modelModelThe model to be exported.
params?ParametersThe parameters to pass to the solver (they are included in the generated code).
warmStart?SolutionAn initial solution to start the solver with.
log?null | WritableStreamThe 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

NameTypeDescription
problemProblemDefinitionThe 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

NameTypeDescription
modelModelThe model to be exported.
params?ParametersThe parameters to pass to the solver (they are mostly unused).
warmStart?SolutionAn initial solution to start the solver with.
log?null | WritableStreamThe 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

NameTypeDescription
sourceParametersInput parameters that can be modified by modifications.
modificationsParametersParameters that will overwrite the parameters from source.

Returns

Parameters

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.