The CLP Procedure

Example 2.15 Resource-Constrained Project Scheduling Problem with Time Windows

(View the complete code for this example.)

The general RCPSP/max (resource-constrained project scheduling problem with time windows) problem can be described as a single project that consists of a set of tasks (activities) that have to be scheduled. Each task requires time and renewable resources in order to be scheduled. In general, tasks are interrelated by two types of constraints:

  • General temporal constraints restrict minimal and maximal time lags between two tasks. The temporal constraint between Task i and Task j has the form

    normal s normal t normal a normal r normal t normal bar normal t normal i normal m normal e left-bracket j right-bracket minus normal s normal t normal a normal r normal t normal bar normal t normal i normal m normal e left-bracket i right-bracket element-of left-bracket normal upper T Subscript i comma j Superscript min Baseline comma normal upper T Subscript i comma j Superscript max Baseline right-bracket

    where normal upper T Subscript i comma j Superscript min and normal upper T Subscript i comma j Superscript max are the minimum and maximum time lags between tasks i and j.

  • Resource constraints enforce the requirement that resource capacities are not exceeded at any time.

The objective of RCPSP/max is to find a feasible schedule that satisfies all temporal and resource constraints and that minimizes the makespan (duration) of the project.

Scheduling with Calendars

In many real-world scheduling problems, resources might not be available at all times, or they might have only partial capacities at some predetermined time periods (for example, because of weekends, holidays, or periods of machine maintenance). For each resource, a calendar indicates the time periods during which the resource is not available or has only partial capacity. The resource calendars impose additional restrictions on the problems.

This example illustrates the use of the cumulative constraint to model resource calendars in solving a single resource-constrained project scheduling problem.

This example considers a simple case of RCPSP/max that uses resource calendars and contains 12 uninterruptible tasks, each with fixed duration and demand. These tasks need to be scheduled on a single renewable resource that has a capacity of eight units. In addition, the resource has only half its capacity available during time period 5 and is unavailable in time period 6.

To simplify the specification, this example considers only the standard finish-to-start precedence relationships between two tasks. That is, Task i immediately precedes Task j, which implies:

normal s normal t normal a normal r normal t normal bar normal t normal i normal m normal e left-bracket j right-bracket minus normal s normal t normal a normal r normal t normal bar normal t normal i normal m normal e left-bracket i right-bracket greater-than-or-equal-to normal d normal u normal r normal a normal t normal i normal o normal n left-bracket i right-bracket

More general forms of temporal relationships that involve nonstandard relationships and lags can be easily formulated using linear constraints.

Table 14 shows the durations, demands, and precedence relations of the tasks.

Table 14: Durations, Demands, and Successors of Tasks

Task Duration Demand Successors
1 1 4 4
2 2 2 5
3 2 3
4 6 3
5 3 2
6 6 3 12
7 1 1 8, 9, 10
8 3 2 11
9 3 2 12
10 4 1 12
11 2 2 12
12 4 2


In order to accommodate the resource calendar, two artificial tasks, Task 13 and Task 14, are introduced, each with a duration of 1. Task 13 starts at time period 5 and uses four units of the resource, leaving half the capacity for other tasks during that period. Similarly, Task 14 starts at time period 6 and consumes the full capacity, thus making the corresponding resource unavailable to other tasks during that period.

Two additional tasks, S and T, are introduced to represent the beginning and completion of the project, respectively. The durations of both S and T are 0, and they do not require any of the resources. Note that the start time and the end time are equal for these two tasks. To simplify the notation, you can use S as the start-time variable of the project and T as the end-time variable. The makespan of the project can be expressed as T – S. Without loss of generality, the start time of the project is assumed to be 0, so that the objective of the problem is to minimize T.

There are two ways to declare start-time variables and specify temporal constraints:

This example illustrates using the Constraint data set, which is created by merging three data sets. The StartTime data set, shown in Output 2.15.1, specifies the lower and upper bounds of the start-time variables for the real and artificial tasks. Note that the domains of artificial variables Start13, Start14, and S are fixed. A lower bound on variable T is determined by considering the (Task 6, Task 12) subpath, and an upper bound on T is determined by aggregating the durations of Task 1 through Task 14. The lower and upper bounds for the other variables are temporarily set to the lower bound of S and the upper bound of T, respectively, for convenience. Tighter bounds will be determined by the precedence constraints.

Output 2.15.1: StartTime Data Set

ObsStart1Start2Start3Start4Start5Start6Start7Start8Start9Start10Start11Start12Start13Start14ST_TYPE__RHS_
1000000000000...10LOWERBD.
2404040404040404040404040...40UPPERBD.
3............560.FIXED.


The Precedence data set shown in Output 2.15.2 specifies linear constraints that represent the precedence relations between tasks.

Output 2.15.2: Precedence Constraints

ObsSStart1Start2Start3Start4Start5Start6Start7Start8Start9Start10Start11Start12T_TYPE__RHS_
1-11............GE0
2-1.1...........GE0
3-1..1..........GE0
4-1.....1.......GE0
5-1......1......GE0
6.-1..1.........GE1
7..-1..1........GE2
8...-1.........1GE2
9....-1........1GE6
10.....-1.......1GE3
11......-1.....1.GE6
12.......-11.....GE1
13.......-1.1....GE1
14.......-1..1...GE1
15........-1..1..GE3
16.........-1..1.GE3
17..........-1.1.GE4
18...........-11.GE2
19............-11GE4


Finally, the Objective data set shown in Output 2.15.3 specifies the objective function of this problem.

Output 2.15.3: Objective Function

ObsT_TYPE__RHS_
11MIN.


The following statements merge these three data sets to create the Constraint data set that the CLP procedure uses to find a schedule that minimizes the makespan.

data ConData;
   set StartTime Precedence Objective;
run;



proc clp condata=ConData out=OutData usecondatavars=1;
   /* set lower and upper bounds for the objective function */
   obj lb=10 ub=40;

   /* Post a cumulative constraint for the resource */
   cumulative (start=(Start1-Start14)
               duration=(1 2 2 6 3 6 1 3 3 4 2 4 1 1)
               demand=(4 2 3 3 2 3 1 2 2 1 2 2 4 8)
               capacity=8);
run;


The USECONDATAVARS=1 specification in the PROC CLP statement indicates that all variables are implicitly defined in the Constraint data table ConData. The OBJ statement specifies the lower and upper bounds on the objective function. In this example, they are actually the lower and upper bounds of variable T, the completion time of the project. The CUMULATIVE statement defines the task start times, task durations, and task demands, and it enforces the constraint that the cumulative resource usage of Task 1 though Task 14 not exceed the resource capacity at any point in time.

The table in Output 2.15.4, which is derived from the solution table, shows a corresponding schedule for the 12 tasks.

Output 2.15.4: RCPSP/max Schedule with Calendars

TaskStartDurationEndDemand
10114
27292
3122143
476133
593122
60663
70111
81342
91342
101451
117292
1294132


The Gantt chart shown in Output 2.15.5 reports the resource demand and displays the resource-constrained schedule for each of the 12 tasks. The chart also overlays a plot of the resource capacity with time and a histogram of the resource demand with time. The resource quantity axis is on the right. Notice the decreased consumption in time periods 5 and 6.

Output 2.15.5: Gantt Chart Showing Task Schedule and Resource Consumption

Gantt Chart Showing Task Schedule and Resource Consumption


Scheduling with Optional Tasks

The second part of this example illustrates how you can use the cumulative constraint to model optional tasks. Optional tasks are tasks that might or might not occur; they can arise in scenarios such as project selection, job contracting, and so on.

Consider the previous resource-constrained project scheduling problem with calendars that completed in 14 time periods. Suppose that the project must now be completed in 12 time periods and can assign certain tasks to external contractors at additional cost in order to complete in fewer time periods. Assume that Task 1, Task 2, Task 3, Task 4, and Task 5 can be contracted out subject to the following pairwise conditions:

  • If Task 1 is contracted out, then Task 4 also be contracted out, and vice-versa. The cost of jointly contracting out Task 1 and Task 4 is $15,000.

  • Similarly, Task 2 and Task 5 must be either jointly contracted out or processed in-house together. The cost of jointly contracting out Task 2 and Task 5 is $12,000.

  • The cost of contracting out Task 3 is $5,000.

The objective is to minimize the total cost, subject to finishing the project within 12 time periods.

The StartTime2 data set shown in Output 2.15.6 specifies the new lower and upper bounds of the start-time variables for all tasks. Note that the variable T is now fixed to 12 to reflect the new makespan restriction. Although not necessary, the upper bounds of all variables Start1 to Start12 can also be set to 12.

Output 2.15.6: StartTime2 Data Set

ObsStart1Start2Start3Start4Start5Start6Start7Start8Start9Start10Start11Start12Start13Start14ST_TYPE__RHS_
1000000000000....LOWERBD.
2121212121212121212121212....UPPERBD.
3............56012FIXED.


One way to model the fact that tasks might or might not be executed in-house is to introduce a demand variable for each such task. The lower bound for this demand variable is equal to 0, and its upper bound is equal to the demand it would have had if it had been processed in-house. The demand variable for a task is assigned to its lower bound if the task is contracted out, or to its upper bound if the task is not contracted out. The usage variables are declared in the Demand data set as shown in Output 2.15.7.

Output 2.15.7: Demand Data Set

ObsDemand1Demand2Demand3Demand4Demand5Demand6Demand7Demand8Demand9Demand10Demand11Demand12Demand13Demand14_TYPE__RHS_
100000.........LOWERBD.
242332.........UPPERBD.
3.....211212248FIXED.


A binary variable is created for each task that can be contracted out. The value of the binary variable is 1 if the corresponding task is contracted out, or 0 if is not contracted out. The relationship between the binary variable normal upper X Subscript i and demand variable normal upper D normal e normal m normal a normal n normal d Subscript i for task i can be expressed by the linear constraint

normal upper D normal e normal m normal a normal n normal d Subscript i Baseline equals normal d normal e normal m normal a normal n normal d left-bracket i right-bracket times left-parenthesis 1 minus normal upper X Subscript i Baseline right-parenthesis

where normal d normal e normal m normal a normal n normal d left-bracket i right-bracket is the demand for the task i.

Because Tasks 1 and 4 and Tasks 2 and 5 must be jointly processed, the number of binary variables can be reduced to three.

upper X 1 equals StartLayout Enlarged left-brace 1st Row 1st Column 1 2nd Column if Task 1 and Task 4 are contracted out 2nd Row 1st Column 0 2nd Column otherwise EndLayout
upper X 2 equals StartLayout Enlarged left-brace 1st Row 1st Column 1 2nd Column if Task 2 and Task 5 are contracted out 2nd Row 1st Column 0 2nd Column otherwise EndLayout
upper X 3 equals StartLayout Enlarged left-brace 1st Row 1st Column 1 2nd Column if Task 3 is contracted out 2nd Row 1st Column 0 2nd Column otherwise EndLayout

The Binary data set shown in Output 2.15.8 declares these three binary variables.

Output 2.15.8: Binary Variables

ObsX1X2X3_TYPE__RHS_
1111BINARY.


The Usage data set shown in Output 2.15.9 contains the linear constraints that relate the binary variables and the demand variables.

Output 2.15.9: Usage Constraints

ObsDemand1Demand2Demand3Demand4Demand5X1X2X3_TYPE__RHS_
11....4..EQ4
2.1....2.EQ2
3..1....3EQ3
4...1.3..EQ3
5....1.2.EQ2


Finally, the objective function shown in Output 2.15.10 defines the total contracting cost of the project that is to be minimized.

Output 2.15.10: Objective Function

ObsX1X2X3_TYPE__RHS_
115125MIN.


As before, the data sets are merged to create the Constraint data table, and the CLP procedure is invoked to find the best solution as follows:

data ConData2;
   set StartTime2 Precedence Demand Binary Usage Objective2;
run;

proc clp condata=ConData2 out=OutData2 usecondatavars=1;
   /* set lower and upper bounds for the objective function */
   obj lb=0 ub=32;

   /* Define a cumulative constraint for the resource */
   cumulative (start=(Start1-Start14)
               demand=(Demand1-Demand14)
               dur=(1 2 2 6 3 6 1 3 3 4 2 4 1 1)
               capacity=8);
run;


The table in Output 2.15.11, derived from the Solution data set, displays the optimal schedule that has a makespan of 11 time periods and contracts out Task 1 and Task 4.

Output 2.15.11: RCPSP Schedule with Optional Tasks

TaskStartDurationEndDemand
20222
37293
52352
60662
70111
81341
91342
101451
114262
1274112


Last updated: September 16, 2021