IBM ILOG Solver User's Manual > Extending the Library > Writing a Goal: Car Sequencing > Writing your own goal > Example of writing your own goal: Implementing IlcInstantiate |
Example of writing your own goal: Implementing IlcInstantiate |
INDEX
![]() |
As an example of goal programming, you are going to look closely at how the function IlcInstantiate
is implemented. This function takes a constrained variable as its argument and binds it. More precisely, this function selects a value in the domain of the constrained variable and assigns it to the constrained variable. Solver automatically propagates the constraints posted on this constrained variable.
With the ideas about choice points and backtracking that you have just learned in mind, now you can implement IlcInstantiate
by means of goals. To do so, you will use the following algorithm:
IlcInstantiate
again. Indeed, this call will try another value from the domain of the constrained variable and repeat the process.Note |
The behavior of IlcInstantiate varies slightly, depending on the class of its arguments. See the IBM ILOG Solver Reference Manual for more detailed information.
|
Assigning a value to (or removing a value from) a constrained variable is straightforward. To do so, use the Solver constraints ==
and !=
.
The Solver code corresponding to IlcInstantiate
for constrained integer variables is quite simple. You will see a couple versions of it to clarify a few points about goals.
As you remember, if you want to define a goal, you use a macro of the form ILCGOALn
, where n
is the number of arguments of the goal. The arguments of ILCGOALn
are the name of the goal, followed by the types and names of the goal's arguments. Then the macro is followed by the body of a C++ function. This body defines how to execute the goal. The return value of that function is the subgoal of the goal defined by the macro itself. When there are no such subgoals, the function must return 0.
Now you can define IlcInstantiate
as a choice point between two goals. Before setting a choice point, Solver checks whether the constrained integer variable has been bound, and if not, Solver selects a value in its domain. The second subgoal recursively calls IlcInstantiate
.
Here is a first version of IlcInstantiate
:
ILCGOAL1(IlcInstantiate, IlcIntVar, var) { if (var.isBound()) return 0; IlcInt value = var.getMin(); return IlcOr( var == value, IlcAnd( var != value, IlcInstantiate(getSolver(), var))); } |
Actually, the ILCGOALn
macros define classes of IlcGoalI
. As a consequence, you can use this
to refer to the current goal. With that possibility in mind, here is a second version of IlcInstantiate
:
ILCGOAL1(IlcInstantiate, IlcIntVar, var) { if (var.isBound()) return 0; IlcInt value = var.getMin(); return IlcOr( var == value, IlcAnd( var != value, this)); } |
(The actual implementation of IlcInstantiate
is slightly different since the choice of the value can be indicated by a parameter, but these two versions indicate the substance of the implementation.)
If you want to have an IloGoal
object returned that can then be passed as a parameter of the IloSolver::solve
and IloSolver:startNewSearch
functions, use the macro ILOCPGOALWRAPPER
.
For example, you can define IloInstantiate
this way:
ILOCPGOALWRAPPER1(IloInstantiate, solver, IloNumVar, x){ return IlcInstantiate(solver, solver.getIntVar(x)); } |
To create an instance of this goal you write:
IloInstantiate(env, x); |
© Copyright IBM Corp. 1987, 2009. Legal terms. | PREVIOUS NEXT |