The CPM Procedure

Multiproject Scheduling

The CPM procedure enables you to define activities in a multiproject environment with multiple levels of nesting. You can specify a PROJECT variable that identifies the name or number of the project to which each activity belongs. The PROJECT variable must be of the same type and length as the ACTIVITY variable. Further, each project can be considered as an activity, enabling you to specify precedence constraints, alignment dates, or progress information for the different projects. Precedence constraints can be specified between two projects, between activities in the same or different projects, or between a project and activities in another project.

The PROJECT variable enables you to specify the name of the project to which each activity belongs. Each project can in turn be treated as an activity that belongs to a bigger project. Thus, the (PROJECT, ACTIVITY) pair of variables enables you to specify multiple levels of nesting using a hierarchical structure for the (task, supertask) relationship.

In the following discussion, the terms superproject, supertask, parent task, ancestor task, project, or subproject refer to a composite task (a task composed of other tasks). A lowest level task (one which has no subtasks under it) is referred to as a child task, descendent task, a leaf task, or a regular task.

You can assign most of the activity attributes to a supertask; however, some of the interpretations may be different. The significant differences are listed as follows.

Activity Duration

Even though a supertask has a value specified for the DURATION variable, the finish time of the supertask may not necessarily be equal to the (start time + duration). The start and finish times of a parent task (supertask) always encompass the span of all its subtasks. In other words, the start (finish) time of a supertask is the minimum start (maximum finish) time of all its subtasks.

The specified DURATION for a supertask is used only if the USEPROJDUR option is specified; this variable is used to compute an upper bound on the late finish time of the project. In other words, you can consider the duration of a supertask as a desired duration that puts a constraint on its finish time.

Note: You cannot specify resource-driven durations for supertasks.

Precedence Constraints

You cannot specify a Start-to-Finish or Finish-to-Finish type of precedence constraint when the Successor task is a supertask. Such a constraint is ignored, and a warning is written to the log.

Time Constraints

The CPM procedure supports all the customary time constraints for a supertask. However, since the supertask does not really have an inherent duration, some of the constraints may lead to unexpected results.

For example, a constraint of the type SLE (Start Less than or Equal to) on a leaf task uses the task’s duration to impose a maximum late finish time for the task. However, for a supertask, the duration is determined by the span of all its subtasks, which may depend on the activities’ calendars. The CPM procedure uses an estimate of the supertask’s duration computed on the basis of the precedence constraints to determine the maximum finish time for the supertask using the date specified for the SLE constraint. Such a constraint may not translate to the correct upper bound on the supertask’s finish time if the project has multiple calendars. The presence of multiple calendars could change the computed duration of the supertask depending on the starting date of the supertask. Thus, in general, it is better to specify SGE (Start Greater than or Equal to) or FLE (Finish Less than or Equal to) constraints on supertasks.

Note that alignment constraints of the type SGE or FLE percolate down the project hierarchy. For example, if there is an SGE specification on a supertask, then all the subtasks of this supertask must also start on or after the specified date.

Mandatory constraints (either of the type MS or MF) are used to set fixed start and finish times on the relevant task. Such constraints are checked for consistency between a parent task and all its descendants.

Progress Information

You can enter progress information for supertasks in the same way as you do for leaf tasks. The procedure attempts to reconcile inconsistencies between the actual start and finish times of a parent and its children. However, it is sufficient (and less ambiguous) to enter progress information only about the tasks at the lowest level.

Resource Requirements

You can specify resource requirements for supertasks in the same way as you do for regular tasks. However, the supertask is scheduled in conjunction with all its subtasks. In other words, a leaf task is scheduled only when its resources and the resources for all its ancestors are available in sufficient quantity. Thus, a supertask needs to have enough resources throughout the schedule of any of its subtasks; in fact, the supertask needs to have enough resources throughout its entire span. In other words, a supertask’s resource requirements are treated as spanning.

In addition to the above treatment of a supertask’s resources, there are two other resource scheduling options available for handling the resource requirements of supertasks. You can use the AGGREGATEPARENTRES option in the PROJECT statement to indicate that a supertask’s resource requirements are to be used only for aggregation. In other words, resource allocation is performed taking into account the resource requirements of only the leaf tasks. Alternately, you can select to ignore any resource requirements specified for supertasks by specifying the IGNOREPARENTRES option. Note the difference between the AGGREGATEPARENTRES and IGNOREPARENTRES options. The first option includes the supertask’s requirements while computing the aggregate resource usage, while the second option is equivalent to setting all parent resource requirements to 0.

Resource-Driven Durations

Any WORK specification is ignored for a parent task. Resources required for a supertask cannot drive the duration of the task; a supertask’s duration is driven by all its subtasks. Note that each leaf task can still be resource driven.

Schedule Computation

The project hierarchy and all the precedence constraints (between leaf tasks, between supertasks, or between a supertask and a leaf task) are taken into consideration when the project schedule is computed. A task (parent or leaf) can be scheduled only when its precedences and all its parent’s precedences are satisfied.

During the forward pass of the scheduling algorithm, all independent start tasks (leaf tasks or supertasks with no predecessors) are initialized to the project start date. Once a supertask’s precedences (if any) are satisfied, all its subtasks whose precedences have been satisfied are added to the list of activities that can be scheduled. The early start times for the subtasks are initialized to the early start time of the supertask and are then updated, taking into account the precedence constraints and any alignment constraints on the activities.

Once all the subtasks are scheduled, a supertask’s early start and finish times are set to the minimum early start and maximum early finish, respectively, of all its subtasks.

The late start schedule is computed using a backward pass through the project network, considering the activities in a reverse order from the forward pass. The late schedule is computed starting with the last activity (activities) in the project; the late finish time for each such activity is set to the master project’s finish date. By default, the master project’s finish date is the maximum of the early finish dates of all the activities in the master project (if a FINISHBEFORE date is specified with the FBDATE option, this date is used as the starting point for the backward calculations).

During the backward pass, the late finish time of a supertask is determined by the precedence constraints and any alignment specification on the supertask. You can specify a finish constraint on a supertask by using the ALIGNDATE and ALIGNTYPE variables, or by using the SEPCRIT or USEPROJDUR option.

If a finish constraint is specified using the ALIGNDATE and ALIGNTYPE specifications, the L_FINISH for the supertask is initialized to this value. If the SEPCRIT option is specified, the supertask’s late finish time is initialized to its early finish time. If the USEPROJDUR option is specified, the late finish time for the supertask is initialized using the early start time of the supertask and the specified supertask duration. The late finish time of the supertask could further be affected by the precedence constraints. Once a supertask’s late finish has been determined, this value is treated as an upper bound on the late finish of all its subtasks.

As with the early start schedule, once all the subtasks have been scheduled, the late start and finish times for a supertask are set to the minimum late start and maximum late finish time, respectively, of all its subtasks.

Schedule Data Set

If a PROJECT variable is specified, the Schedule data set contains the PROJECT variable as well as two new variables called PROJ_DUR and PROJ_LEV.

The PROJ_DUR variable contains the project duration (computed as E_FINISH - E_START of the project) for each superproject in the master project. This variable has missing values for the leaf tasks. It is possible for (L_FINISH - L_START) to be different from the value of PROJ_DUR. If a resource-constrained schedule is produced by PROC CPM, the project duration is computed using the resource constrained start and finish times of the superproject; in other words, in this case PROJ_DUR = (S_FINISH - S_START).

The PROJ_LEV variable specifies the depth of each activity from the root of the project hierarchy tree. The root of the tree has PROJ_LEV = 0; If the project does not have a single root, a common root is defined by the CPM procedure.

The ADDACT option on the PROC CPM statement causes an observation to be added to the Schedule data set for this common root. This observation contains the project start and finish times and the project duration. The ADDACT option also adds an observation for any activity that may appear as a value of the SUCCESSOR or PROJECT variable without appearing as a value of the ACTIVITY variable.

In addition to the PROJ_DUR and PROJ_LEV variables, you can request that a WBS code be added to the output data set (using the option ADDWBS). You can also add variables, ES_ASC, ES_DESC, LS_ASC, LS_DESC, SS_ASC, and SS_DESC, that indicate a sorting order for activities in the output data set. For example, the variable ES_ASC enables you to sort the output data set in such a way that the activities within each superproject are ordered according to increasing early start time.