Variables and expressions
Engine decision variables and expressions are used in the search.
Creation of engine variables
When the model is extracted to an instance of IloCP, generally an instance of
IlcIntVar is automatically created for each IloIntVar in the
model. If no IloExtractable uses the decision variable, it will not be extracted
unless you explicitly add it to the model.
IlcIntVar(IlcCPEngine cp, IlcInt min, IlcInt max, char* name=0);
The constructor declares an engine variable that can take a value between
min and max (its lower and upper boundaries). In other words, the lower and upper
boundaries define the domain of the search decision variable that is being
constructed. The character string name is displayed whenever the variable is
printed. It is an optional argument.
This constructor is intended to be used for creation of search decision variables
inside instances of other computation objects. It should not be used to declare
variables that are part of the problem statement in the modeling layer. That should
be done with the constructor for IloIntVar.
Accessing engine variables
Once an IloIntVar is extracted, you can access
the IlcIntVar from the modeling object IloIntVar
via the IloCPEngine.
The IloCPEngine of the worker under consideration is available in different contexts.
A constraint, a demon, and a goal provide the function
getCPEngine() to get an instance of
IloCPEngine.
A macro for goal or constraint extraction has an
IloCPEngine available as parameter.
The following code returns the IlcIntVar from
an IloIntVar x:
IloIntVar x;
...
IloCPEngine cp = getCPEngine();
IlcIntVar cpx = cp.getIntVar(x);
And now, let us see a complete example for accessing the engine variable during the search process:
ILCGOAL1(MyInst, IlcIntVar, var) {
if (var.isFixed()) return 0;
IlcInt v = var.getMin();
return IlcOr(var == v, IlcAnd(var != v, this));
}
ILCGOAL1(MyGen, IlcIntVarArray, x) {
IloCPEngine cp = getCPEngine();
IlcInt choice = IlcChooseMinSizeInt(x);
if (choice < 0) return 0;
return IlcAnd(MyInst(cp, x[choice]), this);
}
ILOCPGOALWRAPPER1(MyGoal, cp, IloIntVarArray, x) {
return MyGen(cp, cp.getIntVarArray(x)); // cp is of type IloCPEngine here
}
IloEnv env;
IloIntVarArray x(env, 10, 0, 1);
IloModel mdl(env);
mdl.add(x);
IloCP cp(mdl);
cp.solve(MyGoal(env, x));
cout << cp.domain(x) << endl;
This example is a code for defining a custom goal, which will be
defined later in this document. The point here is to focus on the access
to the IlcIntVarArray object corresponding to an
IloIntVarArray given a worker.
This is done in the goal MyGoal defined by the macro
ILOCPGOALWRAPPER1.
When IloCP::solve(MyGoal(env, x)) is called, it creates different workers, each
one having its own IloCPEngine. Each worker executes the code corresponding to
MyGoal, which consists only of mapping the model variables to the engine variables
and creating the IlcGoal (engine goals) on the engine variables. The
cp parameter of the macro ILOCPGOALWRAPPER1 is automatically set
by the solver to the IloCPEngine of the worker under consideration (Warning: it is
not the master IloCP object defined in the main function). The mapping from
IloIntVarArray to IlcIntVarArray is done simply by calling
cp.getIntVarArray(x).