Originally posted by: PhilippeLaborie
For modeling the unloading of the trucks, you should first compute an upper bound on the number of unloading activities that will be required for a truck. Let's call it NbUnloadMax.
Then you would create, for each truck t, a chain of NbUnloadMax optional interval variables representing the unloading activity.
dvar interval unloadingT[u in 1..NbUnloadMax][t in Trucks] optional size LoadDuration;
forall(u in 2..NbUnloadMax) {
endBeforeStart(unloadingT[u-1][t], unloadingT[u][t], 1);
presenceOf(unloadingT[u][t]) => presenceOf(unloadingT[u-1][t]);
}
The loading interval variables will increase the cumul function that represents the load of the truck whereas the unloading will decrease it by a variable amount that depends on the current load of the truck.
// Cummul function for getting loading level of a truck
cumulFunction loading_level[t in Trucks] =
sum(c in collection_point: c>1) stepAtEnd(itvsT[c][t], weight[c]) // LOAD
- sum(u in 1..NbUnloadMax) stepAtStart(unloadingT[u][t], 1, truckCapacity); // UNLOAD
In the constraints of the model you need to state that after unload, the truck is empty. This constraint will ensure that the full content of the truck is unloaded:
forall (t in Trucks){
forall(u in 1..NbUnloadMax) {
alwaysIn(loading_level[t], unloadingT[u][t],0,0);
}
}
You also need to change your model around the "last" activity of the truck as now, you do not know which unlading activity (among the NbUnloadMax ones) will be the last one. I suggest using an additional interval variable that represents the interval of time during which a given truck is performing some unload operations, so this interval spans all the unloading activities of the truck and it will end at the end time of the last present unloading activity. All the loading activities of the truck must end before the end time of this interval:
dvar interval truck[t in Trucks];
forall (t in Trucks){
span(truck[t], all(u in 1..NbUnloadMax) unloadingT[u][t]);
forall(c in collection_point: c>1) {
endBeforeEnd(itvsT[c][t], truck[t]);
}
And you can use the end of this interval in the objective function:
minimize sum(t in Trucks) endOf(truck[t]);
For the extension where you have several trucks, you should use some 'alternative' constraints. I attach the full model.
#ConstraintProgramming-General#DecisionOptimization