You use the macro ILCGOAL1
to define a new class of goals, IlcGenerateAbstractVars
. This goal has one parameter, an array of integer variables. The body of the macro defines how to execute this goal. This goal instantiates each variable using IlcDichotomize
. The function IlcDichotomize creates
and returns a goal that is used to assign a value to a constrained variable. IlcDichotomize
sets a choice point, then replaces the domain of the variable by one of the halves, and calls itself recursively. If failure occurs then, the domain is replaced by the other half, and IlcDichotomize
is called recursively. The function IlcAnd
creates a sequences of subgoals, one for each variable in the array. Here is the code to write the goal:
ILCGOAL1(IlcGenerateAbstractVars, IlcIntVarArray, vars) {
IlcInt index = IlcChooseFirstUnboundInt(vars);
if (index == -1) return 0;
return IlcAnd(IlcDichotomize(vars[index]), this); // first tries vars[index]
== 1
}
|
You use the macro ILOCPGOALWRAPPER
to wrap the goal IlcGenerateAbstractVars
so it can be used in a Concert Technology model as the goal IloGenerateAbstractVars
. Here is the code to wrap the goal
ILOCPGOALWRAPPER1(IloGenerateAbstractVars, solver, IloIntVarArray, vars) {
return IlcGenerateAbstractVars(solver, solver.getIntVarArray(vars));
}
|
In the search, IloSolver::solve
takes the goal IloGenerateAbstractVars
as a parameter. The goal IloGenerateAbstractVars
takes the array of variables tbvars
and the environment as parameters. The filter levels for distribute and sequence constraints are both set to IlcExtended
, the most thorough filter level. The search for solutions itself is carried out by the following code:
IloSolver solver(model);
if (mode) {
solver.setDefaultFilterLevel(IlcSequenceCt,IlcExtended);
solver.setDefaultFilterLevel(IlcDistributeCt,IlcExtended);
}
if (solver.solve(IloGenerateAbstractVars(env,tbvars)))
solver.out() << "cars = " << solver.getIntVarArray(cars) << endl;
else
solver.out() << "No solution" << endl;
solver.printInformation();
}
|