Tank ChooseTank(IloSolver solver, Product p, IlcAnySet tankset) {
Tank best=0;
IloInt eval = IlcIntMax;
for(IlcAnySetIterator it(tankset); it.ok(); ++it) {
Tank tank = (Tank)(*it);
IlcAnySetVar pvar = solver.getAnySetVar(tank->getProductOrders());
if (pvar.isRequired(p))
return tank;
if (! pvar.isPossible(p))
continue;
IloInt size = pvar.getPossibleSet().getSize();
if (size < eval) {
eval = size;
best = tank;
}
}
return best;
}
ILCGOAL2(AssignProduct, Product, product, Truck, truck) {
IloSolver solver = getSolver();
//Choose an already used tank
IlcAnySetVar stanks = solver.getAnySetVar(truck->getTankVar());
Tank tank = ChooseTank(solver, product, stanks.getRequiredSet());
if (tank == 0)
//Choose a new tank
tank = ChooseTank(solver, product, stanks.getPossibleSet());
if (tank == 0)
fail();
IlcAnySetVar stankvar = solver.getAnySetVar(tank->getProductOrders());
if (stankvar.isRequired(product))
return 0;
return IlcOr(IlcMember(product, stankvar),
IlcAnd(IlcNotMember(product, stankvar),
this));
}
ILCGOAL2(AssignProducts, Order, order, Truck, truck) {
IloSolver solver = getSolver();
IlcAnySetVar prodVar = solver.getAnySetVar(order->getProducts());
IlcGoal g = IlcGoalTrue(solver);
for(IlcAnySetIterator it(prodVar.getRequiredSet()); it.ok(); ++it)
g = IloAndGoal(solver, g, AssignProduct(solver, (Product)(*it), truck));
return g;
}