final IntVar[] kid_price = VariableFactory.boundedArray("p2k", n_kids, min_price, max_price, solver);
final IntVar total_cost = VariableFactory.bounded("total cost", min_price*n_kids, max_price * n_kids, solver);
// CD variable
double precision = 1.e-4;
final RealVar average = VariableFactory.real("average", min_price, max_price, precision, solver);
final RealVar average_deviation = VariableFactory.real("average_deviation", 0, max_price, precision, solver);
// continuous views of FD variables
RealVar[] realViews = VariableFactory.real(kid_price, precision);
// kids must have different gifts
solver.post(IntConstraintFactory.alldifferent(kid_gift, "AC"));
// associate each kid with his gift cost
for (int i = 0; i < n_kids; i++) {
solver.post(IntConstraintFactory.element(kid_price[i], gift_price, kid_gift[i]));
}
// compute total cost
solver.post(IntConstraintFactory.sum(kid_price, total_cost));
// compute average cost (i.e. average gift cost per kid)
RealVar[] allRV = ArrayUtils.append(realViews,new RealVar[]{average,average_deviation});
solver.post(new RealConstraint(
"Avg/AvgDev",
"({0}+{1}+{2})/3={3};(abs({0}-{3})+abs({1}-{3})+abs({2}-{3}))/3={4}",
allRV)
);
// set search strategy (ABS)
solver.set(IntStrategyFactory.minDom_LB(kid_gift));
// displays resolution statistics
SearchMonitorFactory.log(solver,true,false);
// print each solution
solver.plugMonitor(new IMonitorSolution() {
@Override
public void onSolution() {
if (LoggerFactory.getLogger("solver").isInfoEnabled()) {
LoggerFactory.getLogger("solver").info("*******************");
for (int i = 0; i < n_kids; i++) {
LoggerFactory.getLogger("solver").info("Kids #{} has received the gift #{} at a cost of {} euros",
new Object[]{i, kid_gift[i].getValue(), kid_price[i].getValue()});
}
LoggerFactory.getLogger("solver").info("Total cost: {} euros", total_cost.getValue());
LoggerFactory.getLogger("solver").info("Average: {} euros per kid", average.getLB());
LoggerFactory.getLogger("solver").info("Average deviation: {} ", average_deviation.getLB());
}
}
});
// find optimal solution (Santa Claus is stingy)
solver.findOptimalSolution(ResolutionPolicy.MINIMIZE,average_deviation, precision);