5.289. sliding_time_window

DESCRIPTIONLINKSGRAPH
Origin

N. Beldiceanu

Constraint

sliding_time_window(WINDOW_SIZE,LIMIT,TASKS)

Argument(s)
WINDOW_SIZEint
LIMITint
TASKScollection(origindvar,durationdvar)
Restriction(s)
WINDOW_SIZE>0
LIMIT0
required(TASKS,​​[origin,duration])
TASKS.duration0
Purpose

For any time window of size WINDOW_SIZE, the intersection of all the tasks of the collection TASKS with this time window is less than or equal to a given limit LIMIT.

Example
(
9,6,
origin10duration3,
origin5duration1,
origin6duration2,
origin14duration2,
origin2duration2
)

The lower part of Figure 5.289.1 indicates the different tasks on the time axis. Each task is drawn as a rectangle with its corresponding identifier in the middle. Finally the upper part of Figure 5.289.1 shows the different time windows and the respective contribution of the tasks in these time windows. Observe that we only need to focus on those time windows starting at the start of one of the tasks. A line with two arrows depicts each time window. The two arrows indicate the start and the end of the time window. At the left of each time window we give its occupation. Since this occupation is always less than or equal to the limit 6, the sliding_time_window constraint holds.

Figure 5.289.1. Time windows of the sliding_time_window constraint
ctrs/sliding_time_window1
Usage

The sliding_time_window constraint is useful for timetabling problems in order to put an upper limit on the total work over sliding time windows.

Reformulation

The sliding_time_window constraint can be expressed in term of a set of |TASKS|2 reified constraints and of |TASKS| linear inequalities constraints:

  1. For each pair of tasks TASKS[i],TASKS[j] (i,j[1,|TASKS|]) of the TASKS collection we create a variable Interij which is set to the intersection of TASKS[j] with the time window Wi of size WINDOW_SIZE that starts at instant TASKS[i].origin:

    • If i=j (i.e., TASKS[i] and TASKS[j] coincide):

      • Interij=min(TASKS[i].duration,WINDOW_SIZE).

    • If ij and TASKS[j].origin+TASKS[j].duration<TASKS[i].origin (i.e., TASKS[j] for sure ends before the time window Wi):

      • Interij=0.

    • If ij and TASKS[j].origin>TASKS[i].origin+WINDOW_SIZE1 (i.e., TASKS[j] for sure starts after the time window Wi):

      • Interij=0.

    • Otherwise (i.e., TASKS[j] can potentially overlap the time window Wi):

      • Interij=max(0,min(TASKS[i].origin+WINDOW_SIZE,TASKS[j].origin+TASKS[j].duration)max(TASKS[i].origin,TASKS[j].origin)).

  2. For each task TASKS[i] (i[1,|TASKS|]) we create a linear inequality constraint Interi1+Interi2+...+Interi|TASKS|LIMIT.

See also

shift, sliding_time_window_from_start, sliding_time_window_sum.

Key words

constraint type: sliding sequence constraint, temporal constraint.


Arc input(s)

TASKS

Arc generator
CLIQUEcollection(tasks1,tasks2)

Arc arity
2
Arc constraint(s)
tasks1.origintasks2.origin
tasks2.origintasks1.origin<WINDOW_SIZE
Sets
SUCC[source,tasks]

Constraint(s) on sets
sliding_time_window_from_start(WINDOW_SIZE,LIMIT,tasks,source.origin)


Graph model

We generate an arc from a task t1 to a task t2 if task t2 does not start before task t1 and if task t2 intersects the time window that starts at the origin of task t1. Each set generated by SUCC corresponds to all tasks that intersect in time the time window that starts at the origin of a given task.

Parts (A) and (B) of Figure 5.289.2 respectively show the initial and final graph associated with the Example slot. In the final graph, the successors of a given task t correspond to the set of tasks that do not start before task t and intersect the time window that starts at the origin of task t.

Figure 5.289.2. Initial and final graph of the sliding_time_window constraint

ctrs/sliding_time_windowActrs/sliding_time_windowB
(a) (b)