Originally posted by: ChrisBr
Hello WeeLoon,
For the sake of simplicity, the samples are given here in OPL; of course, every features are available in other APIs (C++, Java, .Net, Python).
Let's say
N: the number of tasks
D: the setup time
X: the time spent between 2 tasks which requires a setup
And the interval vars:
int taskSizes[i in 1..N] = 10;
dvar interval tasks[i in 1..N] size taskSizes[i];
The idea is to define for each task an optional interval var setup linked to its corresponding task using a span constraint and covering interval var covers.
dvar interval setup[i in 1..N] optional size D;
dvar interval covers[i in 1..N] size taskSizes[i]..horizon;
forall(i in 1..N)
span(covers[i], append(tasks[i], setup[i]));
Note that if tasks may be optional, covers must be optional also and their presence must be equals.
forall(i in 1..N)
presenceOf(tasks[i]) == presenceOf(covers[i]);
It is possible also to strengthen the proximity of the setup and its corresponding task by limiting the size of the covering interval:
dvar interval covers[i in 1..N] size taskSizes[i]..(taskSizes[i]+D);
Then the tasks have to be sequenced; actually we sequence the couples "setup-task", so we sequence the covering intervals
dvar sequence seq in all(i in 1..N) covers[i];
noOverlap(seq);
The constraint which manages the presence or not of setup depending on the distance between 2 tasks inside the sequence is:
forall(i in 1..N)
presenceOf(setup[i]) == (startOf(tasks[i],0) - endOfPrev(seq, covers[i],0,0) > X);
It is possible also to try to avoid too much setup:
minimize sum(i in 1..N) presenceOf(setup[i]);
Note that it would be better to set a searchPhase on the interval vars tasks which are the true decision variables:
cp.setSearchPhases(f.searchPhase(tasks));
I hope this helps,
Chris
#CPOptimizer#DecisionOptimization