The counting expression
Inference levels can be used to adjust the propagation of the counting expression.
The specialized counting expression counts the number of times a value appears in the domain of a set of variables. This is useful to count or to constrain the number of times an object or a feature is selected or used.
For instance, assume there are 5 customers, and for each customer, a supplier needs to be chosen. For each customer, there is a list of compatible suppliers. Supplier 1 must not supply more than 2 customers, and the expensive Supplier 2 must not supply more than one customer.
To model the compatibility between suppliers and customers, a decision variable is introduced for each customer that will be fixed to the value of the supplier that supplies it:
IloIntVarArray cust(env);
cust.add(IloIntVar(env, 1, 2));
cust.add(IloIntVar(env, 1, 2));
cust.add(IloIntVar(env, 1, 2));
cust.add(IloIntVar(env, 0, 5));
cust.add(IloIntVar(env, 1, 3));
The constraints can then be expressed the following way:
IloModel model(env);
model.add(IloCount(cust, 1) <= 2);
model.add(IloCount(cust, 2) <= 1);
To propagate the constraints of the model add:
IloCP cp(model);
if (cp.propagate())
cp.out() << " Domains of cust are " << cp.domain(cust) << std::endl;
else
cp.out() << " Model has no solution." << std::endl;
Running this program produces the output:
Domains of cust are [[1..2] [1..2] [1..2] [0..5] [1..3]]
Using the default inference level of the constraint does not result in any domain reduction. To get the highest level of domain reduction on this example, the inference level can be set to the extended level by adding:
cp.setParameter(IloCP::CountInferenceLevel, IloCP::Extended);
The output becomes:
Domains of cust are [[1..2] [1..2] [1..2] [0 3..5] [3]]
Since values 1 and 2 are the only values in the domain
of cust[0], cust[1] and cust[3],
the counting constraints impose that one of these variables will have
the value 2 and two of them will have the value 1. Therefore these
values are removed from the domains of cust[3] and cust[4].
Setting the inference level of the counting expression to the basic or the low level provides basic but efficient domain reduction. Setting the inference level to the medium level provides a stronger reduction but on bounds only. Finally, setting the inference level to the extended level provides full domain reduction.