Originally posted by: PhilippeLaborie
Note that you can also avoid the enumeration of the values and also produce a step function at the end by manipulating steps of the function as tuples. Here is an example that takes as input a set of "non-availability" time windows and compute their union as a step function.
The idea is to traverse the availability/non-availability events in chronological order (that is the goal of the sorted set of events "Steps") and create steps of the resulting function on the fly.
Note that if you are using another API than OPL (C++, Python,Java), you can just do some min/max operations on the step functions: f = max(f1,f2).
tuple TimeWindow { int s; int e; }
{TimeWindow} NonAvailable1 = { <0,10>, <50,80>, <90,100> };
{TimeWindow} NonAvailable2 = { <0,5>, <15,20>, <25,30>, <50,55>, <80,90>, <120,125> };
{TimeWindow} NonAvailable = NonAvailable1 union NonAvailable2;
tuple Step { int x; int v; int i; };
sorted {Step} Steps =
{ <w.s, 1, ord(NonAvailable,w) > | w in NonAvailable } union
{ <w.e, -1, ord(NonAvailable,w) > | w in NonAvailable };
{Step} Result = {};
execute {
var na = 0;
for (var s in Steps) {
if (na==0) {
Result.add(s.x,1,0);
}
na += s.v;
if (na==0) {
Result.add(s.x,0,0);
}
}
}
stepFunction ForbiddenTimes = stepwise (s in Result) { s.v -> s.x; 100 };
execute {
writeln(ForbiddenTimes);
}
#DecisionOptimization#OPLusingCPOptimizer