As you search for an assignment of orders to trucks, you first try to assign the largest order, that is, the order with the greatest quantity. For a given order, you first try the "hardest" truck; that is, the one with the smallest domain; in other words, the one for which you have the fewest possible choices of orders that fit.
Here is the goal to choose the hardest truck to fill:
Truck ChooseTruck(IloSolver solver,
Order order,
IloInt nbTrucks, IloArray<Truck> trucks,
IlcBool aNewOne) {
Truck best=0;
IloInt eval = IlcIntMax;
for(IloInt i=0; i < nbTrucks; i++) {
IlcAnySetVar oVar = solver.getAnySetVar(trucks[i]->getOrders());
IloInt cardMin = IlcCard(oVar).getMin();
if (aNewOne) {
if (cardMin > 0)
continue;
} else {
if (cardMin == 0)
continue;
if (oVar.isRequired(order))
return trucks[i];
}
if (! oVar.isPossible(order))
continue;
IloInt size = oVar.getPossibleSet().getSize();
if (size < eval) {
eval = size;
best = trucks[i];
}
}
return best;
}
ILCGOAL3(AssignOrder, Order, order, IloInt, nbTrucks, IloArray<Truck>, trucks) {
IloSolver solver = getSolver();
//Choose first an already used truck
Truck t = ChooseTruck(solver, order, nbTrucks, trucks, IlcFalse);
if (t == 0) {
//Choose a new truck
t = ChooseTruck(solver, order, nbTrucks, trucks, IlcTrue);
}
if (t == 0)
fail();
IlcAnySetVar tVar = solver.getAnySetVar(t->getOrders());
if (tVar.isRequired(order))
return AssignProducts(solver, order, t);
else
return IlcOr(IlcAnd(IlcMember(order, tVar),
AssignProducts(solver, order, t)),
IlcAnd(IlcNotMember(order, tVar),
this));
}
ILOCPGOALWRAPPER3(IloAssignOrder, solver, Order, ord, IloInt, nbTrucks, IloArray<Truck>, trucks) {
return AssignOrder(solver, ord, nbTrucks, trucks);
}
IloGoal IloAssignOrders (IloEnv env, IloAnyArray orders, IloInt nbTrucks, IloArray<Truck> trucks) {
IloGoal goal = IloGoalTrue(env);
for(IloInt i = 0; i < orders.getSize(); i++)
goal = goal && IloAssignOrder(env, (Order)orders[i], nbTrucks, trucks);
return goal;
}
IloGoal IloEliminateTrucks (IloEnv env, IloInt nbTrucks, IloInt nbMax, IloArray<Truck> trucks) {
IloGoal goal = IloGoalTrue(env);
for(IloInt i = nbTrucks; i > nbMax; i--)
goal = goal && IloAddConstraint(trucks[i-1]->getUsed() == 0);
return goal;
}