Originally posted by: Petr Vilím
Hello,
here is a solution suggested by my colleague. For simplicity I will call the real tasks (interval assigment in your model) Ai where i is an index. The idea is to introduce for each Ai another optional interval Bi such that:
presenceOf(Bi) => presenceOf(Ai)
startAtStart(Ai,Bi)
endAtEnd(Ai,Bi)
For a given batch, we want that one and only one of the Bi corresponding to the Ais in the batch is present, this Bi will represent the "batch interval". This can be done by creating a cumul function (only one for the machine) :
batch = sum_i pulse(Bi,1)
And:
alwaysIn(batch,Ai,1,1)
So Ai requires batch cumul function to be 1 during Ai. Therefore some Bi must be present in order to increase the value of batch cumul function. However not more than one Bi could be present because then the value of the cumul function would be too high. You can use intervals Bi to increase dirtiness of the resource accordingly. The cost of the extra modeling is not huge and the intervals Bi are always synchronized with the Ai so they will be fixed more or less together in the search.
One can also post the redundant constraint:
batch <= 1
And maybe (though they can be less useful):
alwaysIn(batch,Bi, 1, 1)
noOverlap([Bi])
Experiment with those constraints for yourself whether they help (and it is always recommended to experiment with multiple data sets or at least multiple settings of RandomSeed parameter in order to avoid making decisions based on just one run since one run could be just very lucky/unlucky).
The only issue with this model is the introduction of many symmetries due to the selection of which Bi is present in a given batch. I.e. there are many equivalent solutions that differs only in selection of Bi. This can be fixed by using an additional state function (again, only one for the machine) 'minID' with the following constraints:
alwaysIn(minID,Ai,0,i)
alwaysEqual(minID,Bi,i)
This will ensure that among the Bis in a batch only the one corresponding to the smallest index i in the batch is selected. Again, try for yourself, sometimes breaking symmetries is counterproductive.
Best regards, Petr
#DecisionOptimization#OPLusingCPOptimizer