Overview | Group | Tree | Graph | Index | Concepts |
You can use the function IlcDistribute
to count the number of
occurrences of several values among the constrained variables in an array of
constrained variables. (See the functions IlcCard
and IlcSetOf
for other counting constraints.)
This function creates and returns a constraint. That constraint has no effect until
you post it. When this constraint is posted, then the constrained variables in the array
cards
are equal to the number of occurrences in the array vars
of the values in the array values
. More precisely, for each i
,
cards[i]
is equal to the number of occurrences of values[i]
in
the array vars
. After propagation of this constraint, the minimum of
cards[i]
is at least equal to the number of variables contained in
vars
bound to the value at values[i]
; and the maximum of
cards[i]
is at most equal to the number of variables contained in vars
that contain the value at values[i]
in their domain.
The arrays cards
and values
must be the same length; otherwise,
Solver will throw an exception (an instance of IloSolver::SolverErrorException
).
When this function has only two arguments (that is, there is no values
parameter),
then the array of values that are being counted must be an array of consecutive integers starting
with 0 (zero). In that case, for each i
, cards[i]
is equal to the number
of occurrences of i
in the array vars
. After propagation of this constraint,
the minimum of cards[i]
is at least equal to the number of variables contained in
vars
bound to the value i
; and the maximum of cards[i]
is at most equal to the number of variables contained in vars
that contain
i
in their domain.
If you do not explicitly state a filter level, then Solver will use the default filter
level for this constraint. The optional argument level
can take either of two
values: IlcBasic
or IlcExtended
. Its lowest value is IlcBasic
.
The amount of domain reduction during propagation depends on that value. See
IlcFilterLevel
for an explanation of filter levels and their
effect on constraint propagation.
IlcBasic
makes the statement
s.add(IlcDistribute(cards, values, vars));
more efficient and causes more domain reductions than the following code:
IlcIndex j; IlcInt size = cards.getSize(); for (IlcInt i = 0; i < size; i++) s.add(cards[i] == IlcCard(j, vars[j] == values[i]) );
IlcExtended
causes more domain reduction than IlcBasic
; it also
takes longer to run.
Adding These Constraints
You may add these constraints only during a Solver search; that is, inside a goal (an instance of
IlcGoal
) or inside a constraint (an instance of
IlcConstraint
). If you are looking for similar functionality in a
constraint to add to a model, see IloDistribute
documented in the IBM ILOG
Concert Technology Reference Manual.
Programming Hint
This statement:
s.add(IlcDistribute(cards, values, vars));
is more efficient than but equivalent to the following code:
assert(cards.getSize() == values.getSize()); IlcInt i; IlcIndex j; IlcInt size = cards.getSize(); for(i=0; i<size; i++) s.add(cards[i] == IlcCard(j, vars[j] == values[i]));
Programming Hint
This statement:
s.add(IlcDistribute(cards, vars));
is more efficient than but equivalent to the following code:
IlcInt size = cards.getSize(); IlcIntArray values(size); for(IlcInt i = 0; i < size; i++) values[i] = i; s.add(IlcDistribute(cards, values, vars));
See Also:
IlcAbstraction, IlcCard, IlcConstraint, IlcFilterLevel, IlcIndex, IlcSequence, IlcSetOf