Module docplex.cp.blackbox

A blackbox expression is a numerical expression for which the analytical form is not known or cannot be formulated using CP Optimizer’s classical expressions. A blackbox expression is specified by giving a function that evaluates the expression at given points.

This feature is accessible from Python only for CPLEX Studio versions 22.1 and later.

Defining a blackbox function

A blackbox function is defined by an instance of the class CpoBlackboxFunction that contains:

  • the name of the blackbox function, auto-allocated if not given,
  • the number of values that are returned by the evaluation of the function, one by default,
  • the list of argument types, auto-determined if not given,
  • the implementation of the function,
  • optionally an argument to pass known result bounds when evaluating the function,
  • an indicator allowing parallel evaluation of the blackbox function, False by default.

Each argument type can be given using its symbolic name string, or using its corresponding type descriptor constant object of class CpoType listed in module catalog. Allowed argument types are:

  • ‘Int’ or Type_Int
  • ‘IntVar’ or Type_IntVar
  • ‘IntExpr’ or Type_IntExpr
  • ‘Float’ or Type_Float
  • ‘FloatExpr’ or Type_FloatExpr
  • ‘IntervalVar’ or Type_IntervalVar
  • ‘SequenceVar’ or Type_SequenceVar
  • ‘IntArray’ or Type_IntArray
  • ‘IntVarArray’ or Type_IntVarArray
  • ‘IntExprArray’ or Type_IntExprArray
  • ‘FloatArray’ or Type_FloatArray
  • ‘FloatExprArray’ or Type_FloatExprArray
  • ‘IntervalVarArray’ or Type_IntervalVarArray
  • ‘SequenceVarArray’ or Type_SequenceVarArray

If not given, the list of argument types is automatically computed as the smallest list of types that are common to all the references to the blackbox function in the model.

Evaluating a blackbox function

The implementation of the function is a function or a lambda expression that takes as many parameters as declared in the list of argument types. If the blackbox definition parameter args_with_vars is not set to True (default value is False), the arguments are limited to their values. If it is set to True, then the argument is an object of class CpoXxxVarSolution every time the argument type explicitly refers to a variable. This allows to access to the model variable, that constitute the argument, if available. In such case:

  • argument variable can be accessed with method get_var(),
  • argument value can be accessed with method get_value().

Here is what is given as argument value for each argument type if args_with_vars is set to False (default):

  • ‘Int’: integer constant.
  • ‘IntVar’: integer constant.
  • ‘IntExpr’: integer constant.
  • ‘Float’: float constant.
  • ‘FloatExpr’: float constant.
  • ‘IntervalVar’: interval variable solution value, named tuple containing start, end and size of the variable.
  • ‘SequenceVar’: sequence variable solution value, ordered list of model interval variables in the sequence.
  • ‘IntArray’: list of integer constants.
  • ‘IntVarArray’: list of integer constants.
  • ‘IntExprArray’: list of integer constants.
  • ‘FloatArray’: list of float constants.
  • ‘FloatExprArray’: list of float constants.
  • ‘IntervalVarArray’: list of interval variable solution value (see ‘IntervalVar’).
  • ‘SequenceVarArray’: list of sequence variable solution value (see ‘SequenceVar’).

Here is what is given as argument value for each argument type if args_with_vars is explicitly set to True:

  • ‘Int’: integer constant.
  • ‘IntVar’: object of CpoIntVarSolution.
  • ‘IntExpr’: integer constant.
  • ‘Float’: float constant.
  • ‘FloatExpr’: float constant.
  • ‘IntervalVar’: object of CpoIntervalVarSolution.
  • ‘SequenceVar’: object of CpoSequenceVarSolution.
  • ‘IntArray’: list of integer constants.
  • ‘IntVarArray’: list of objects of CpoIntVarSolution.
  • ‘IntExprArray’: list of integer constants.
  • ‘FloatArray’: list of float constants.
  • ‘FloatExprArray’: list of float constants.
  • ‘IntervalVarArray’: list of objects of class CpoIntervalVarSolution.
  • ‘SequenceVarArray’: list of objects of class CpoSequenceVarSolution, with value as list of objects of class CpoSequenceVar.

The function may return:

  • one or several float results in a list,
  • a single number value, automatically converted in a list with this single value,
  • a boolean value, converted as an integer 0 or 1 put in a single value list,
  • None, if the function has no solution for these arguments.

If an error occurs during the function evaluation, the exception is forwarded to the solver that will fail with this error.

If an exception is thrown, it is propagated to the solver that rethrow an exception to exit from the solve.

As the evaluation of the blackbox function is required by the different CPO workers, multiple evaluation requests may happen concurrently. As Python does not support real multi-threading (see Global Interpreter Lock here: https://wiki.python.org/moin/GlobalInterpreterLock), concurrent processing may introduce overhead, or computation problems if the blackbox evaluation uses services of libraries that are not designed to run concurrently. By default, blackbox function evaluation is then executed in mutual exclusion, but this can be changed by setting the parameter parallel to True, or using method set_parallel_eval()

To avoid calling the blackbox function multiple times with the same parameters, the solver can use a cache that may be configured at the declaration of the blackbox. This cache is by default local to each call instance of the blackbox function in the model, in case the evaluation of the function depends on the calling context and may return different results with the same parameters depending where the call is placed in the model.

Using a blackbox function in a model

Once defined, the blackbox function can be used in a model simply by calling the blackbox function descriptor with appropriate model expressions as arguments. Following is a simple example that shows how to use a blackbox function with 2 parameters:

bbf = CpoBlackboxFunction(lambda x, y: x + y)
mdl = CpoModel()
v1 = integer_var(0, 10, "V1")
v2 = integer_var(0, 10, "V2")
mdl.add(bbf(v1, v2) == 5)

If the blackbox function returns multiple values, using the function in a model is done in two steps, as follows:

bbf = CpoBlackboxFunction(impl=lambda x, y: (x + y, x - y), dimension=2)
mdl = CpoModel()
v1 = integer_var(0, 10, "V1")
v2 = integer_var(0, 10, "V2")
a, b = bbf(v1, v2)
mdl.add(a + b == 4)

Note that not all returned expressions need to be used in the model.

Detailed description

class docplex.cp.blackbox.CpoBlackboxFunction(impl=None, dimension=1, argtypes=None, name=None, parallel=False, bounds_parameter=None, args_with_vars=False, cachesize=-1, globalcache=False)[source]

Bases: object

This class represents the descriptor of a blackbox function.

A blackbox function is defined by:

  • a name, that must not be equal to an existing modeling operation,
  • the number of float values it returns (the dimension),
  • the list argument types,
  • the implementation of the function, that evaluates the result from a list of fully evaluated arguments.
  • a parameter allowing to pass the known bounds of the result.

Each argument type can be given using its symbolic name string, or using its corresponding type descriptor constant object of class CpoType listed in module catalog.

Allowed argument types are:

  • ‘Int’ or Type_Int
  • ‘IntVar’ or Type_IntVar
  • ‘IntExpr’ or Type_IntExpr
  • ‘Float’ or Type_Float
  • ‘FloatExpr’ or Type_FloatExpr
  • ‘IntervalVar’ or Type_IntervalVar
  • ‘SequenceVar’ or Type_SequenceVar
  • ‘IntArray’ or Type_IntArray
  • ‘IntVarArray’ or Type_IntVarArray
  • ‘IntExprArray’ or Type_IntExprArray
  • ‘FloatArray’ or Type_FloatArray
  • ‘FloatExprArray’ or Type_FloatExprArray
  • ‘IntervalVarArray’ or Type_IntervalVarArray
  • ‘SequenceVarArray’ or Type_SequenceVarArray

Constructor

The list of function argument types is optional. If not given, it is automatically determined as the most common types of the expression arguments used in its different references in the model.

Function implementation is optional. This allows to parse a CPO file that contains references to blackbox functions(s), which requires to register them in the model prior to parse it. However, the model will not be able to be solved.

The name of the function is optional. If not given, a name is automatically allocated when solving the model. If given, the name of the function must be a symbol (only letters and digits, starting by a letter) that is not already used as the name of an existing modeling function.

Bound parameter is optional. If defined, the known bounds of the function result is passed to the function implementation using this named parameter. If the dimension of the function is 1, the bounds is a simple tuple containing lower and upper bounds. Otherwise, the bounds is a list of tuples, one for each returned value. If unknown, bounds are set to -inf or inf (float(“inf”) in Python).

By default, arguments passed when evaluating the function are only values. If the parameter include_vars is set to True, when arguments are variables, an object of type CpoXxxVarSolution, that include reference to the model variable, is used instead.

A cache can be used by the solver to avoid calling the blackbox function multiple times with the same values. By default (cachesize=-1), the size of the cache is automatically determined by the solver, but it can be forced to a given value, or zero for no cache at all.

By default, this cache is local to each call instance of the blackbox function in the model, in case the evaluation of the function depends on the calling context and may return different results with the same parameters depending where the call is placed in the model. The parameter globalcache can be set to True if the same cache can be used for all call instances.

Parameters:
  • impl – (Optional) Implementation of the function
  • dimension – (Optional) Number of float values that are returned by the function. Default is 1.
  • argtypes – (Optional) List of argument types or type names.
  • name – (Optional) Name of the function, restricted to symbol.
  • parallel – (Optional) Indicates that the blackbox function evaluation is allowed concurrently. Default is False.
  • bounds_parameter – (Optional) Name of the parameter in which known return values bounds can be set. Default is None.
  • args_with_vars – (Optional) Enable passing an object of type CpoXxxVarSolution instead of value only. Default is False.
  • cachesize – (Optional) Indicates that the blackbox function evaluation is allowed concurrently. Default value is -1, indicating that the cache is managed by the solver with default settings.
  • globalcache – (Optional) Indicates that the same cache can be used for all blackbox function call instances in the model. Default is False.
build_model_call(*args)[source]

Build a model expression representing a call to this blackbox function.

Parameters:*args – List of expressions that are arguments of the function
Returns:List model expressions representing access to the unitary result values, or single result if dimension is 1.
eval(*args)[source]

Evaluate the function from the list of parameter values

This function evaluates the blackbox function without providing bounds.

Parameters:*args – List of parameter values
Returns:List of result float values
get_arg_types()[source]

Get the list of argument types

Returns:List of argument types, objects of class CpoType
get_cache_size()[source]

Get the size of the evaluation cache

Returns:Evaluation cache size, -1 for default, 0 for none.
get_dimension()[source]

Get the dimension of this blackbox function

Returns:Number of result values (size of the result list or array)
get_eval_count()[source]

Get the number of times this blackbox function has been evaluated

Returns:number of times this blackbox function has been evaluated
get_implementation()[source]

Get the blackbox function implementation

Returns:Blackbox function implementation
get_name()[source]

Get the name of the blackbox function

Returns:Name of the blackbox function
has_implementation()[source]

Get if the blackbox function has an implementation

Returns:True if the blackbox function has an implementation
is_global_cache()[source]

Check if a global cache has been set.

Returns:True if there is a global cache for this function.
is_parallel_eval()[source]

Check if parallel evaluation is allowed.

Returns:True if parallel evaluation is allowed, false oherwise
reset_eval_count()[source]

Reset the number of times this blackbox function has been evaluated

set_cache_size(size)[source]

Set the size of evaluation cache.

Parameters:size – Cache size, -1 for default, 0 for none.
set_dimension(dim)[source]

Set the dimension of this blackbox function, i.e. the number of values that it returns.

Parameters:dim – Number of result values (size of the result list or array)
set_global_cache(glob)[source]

Set the global cache indicator.

When set, there is a single evaluation cache for all the blackbox function call instances.

Parameters:glob – Global cache indicator
set_implementation(impl)[source]

Set the blackbox function implementation

Parameters:impl – Blackbox function implementation
set_name(nm)[source]

Set the name of the blackbox function

Parameters:nm – Name of the blackbox function
set_parallel_eval(par)[source]

Set parallel evaluation enablement indicator.

Parameters:par – Parallel evaluation indicator.
class docplex.cp.blackbox.CpoBlackboxFunctionCall(bbf, oprnds)[source]

Bases: docplex.cp.expression.CpoFunctionCall

This class represent all model expression nodes that call a blackbox function.

Constructor :param bbf: Blackbox function descriptor :param oprnds: List of operand expressions.