Example 2.24: Multiproject Scheduling
This example illustrates multiproject scheduling.
Consider a Survey project that contains three phases, Plan, Prepare,
and
Implement, with each phase containing more than one activity. You can
consider each phase of the project as a subproject within the
master project, Survey. Each subproject in turn contains the
lowest level activities, also referred to as the leaf tasks. The
Activity data set, containing the task durations, project hierarchy, and
the precedence constraints, is displayed in Output 2.24.1.
The PROJECT and ACTIVITY variables together define the project
hierarchy using the parent/child relationship. Thus, the subproject,
`Plan', contains the two leaf tasks, `plan sur' and
`design q'. Precedence constraints are specified between leaf
tasks as well as between subprojects. For example, the subproject
`Prepare' is followed by the subproject `Implement'.
Durations are specified for all the tasks in the project, except for the
master project `Survey'.
In addition to the Activity data set, define a Holiday data
set, also displayed in Output 2.24.1.
Output 2.24.1: Survey Project
Survey Project |
Activity Data Set SURVEY |
Obs |
id |
activity |
duration |
succ1 |
succ2 |
succ3 |
project |
1 |
Plan Survey |
plan sur |
4 |
hire per |
design q |
|
Plan |
2 |
Hire Personnel |
hire per |
5 |
trn per |
|
|
Prepare |
3 |
Design Questionnaire |
design q |
3 |
trn per |
select h |
print q |
Plan |
4 |
Train Personnel |
trn per |
3 |
|
|
|
Prepare |
5 |
Select Households |
select h |
3 |
|
|
|
Prepare |
6 |
Print Questionnaire |
print q |
4 |
|
|
|
Prepare |
7 |
Conduct Survey |
cond sur |
10 |
analyze |
|
|
Implement |
8 |
Analyze Results |
analyze |
6 |
|
|
|
Implement |
9 |
Plan |
Plan |
6 |
|
|
|
Survey |
10 |
Prepare |
Prepare |
8 |
Implement |
|
|
Survey |
11 |
Implement |
Implement |
18 |
|
|
|
Survey |
12 |
Survey Project |
Survey |
. |
|
|
|
|
Survey Project |
Holiday Data Set HOLIDATA |
|
The following statements invoke PROC CPM with a PROJECT statement
identifying the parent task for each subtask in the Survey project.
The calendar followed is a weekday calendar with a holiday defined
on April 14, 1995. The ORDERALL option on the PROJECT statement
creates the ordering variables ES_ASC and LS_ASC in the Schedule
data set, and the ADDWBS option creates a work breakdown structure
code for the project. The Schedule data set is displayed in Output 2.24.2,
after being sorted by the variable ES_ASC.
Note that the PROJ_DUR variable is missing for all the leaf
tasks, and it contains the project duration for the supertasks.
The project duration is computed as the span of all the subtasks
of the supertask. The PROJ_LEV variable specifies the level of
the subtask within the tree defining the project hierarchy, starting
with the level `0' for the master project (or the root),
`Survey'. The variable WBS_CODE contains the Work Breakdown
Structure code defined by the CPM procedure using the project
hierarchy.
proc cpm data=survey date='3apr95'd out=survout1
interval=weekday holidata=holidata;
activity activity;
successor succ1-succ3;
duration duration;
id id;
holiday hol;
project project / orderall addwbs;
run;
proc sort;
by es_asc;
run;
title 'Conducting a Market Survey';
title2 'Early and Late Start Schedule';
proc print;
run;
Output 2.24.2: Survey Project Schedule
Conducting a Market Survey |
Early and Late Start Schedule |
Obs |
project |
PROJ_DUR |
PROJ_LEV |
WBS_CODE |
activity |
succ1 |
succ2 |
succ3 |
duration |
id |
E_START |
E_FINISH |
L_START |
L_FINISH |
T_FLOAT |
F_FLOAT |
ES_ASC |
LS_ASC |
1 |
|
28 |
0 |
0 |
Survey |
|
|
|
. |
Survey Project |
03APR95 |
11MAY95 |
03APR95 |
11MAY95 |
0 |
0 |
0 |
0 |
2 |
Survey |
7 |
1 |
0.0 |
Plan |
|
|
|
6 |
Plan |
03APR95 |
11APR95 |
03APR95 |
12APR95 |
1 |
1 |
1 |
1 |
3 |
Plan |
. |
2 |
0.0.0 |
plan sur |
hire per |
design q |
|
4 |
Plan Survey |
03APR95 |
06APR95 |
03APR95 |
06APR95 |
0 |
0 |
2 |
2 |
4 |
Plan |
. |
2 |
0.0.1 |
design q |
trn per |
select h |
print q |
3 |
Design Questionnaire |
07APR95 |
11APR95 |
10APR95 |
12APR95 |
1 |
0 |
3 |
3 |
5 |
Survey |
8 |
1 |
0.1 |
Prepare |
Implement |
|
|
8 |
Prepare |
07APR95 |
19APR95 |
07APR95 |
19APR95 |
0 |
0 |
4 |
4 |
6 |
Prepare |
. |
2 |
0.1.0 |
hire per |
trn per |
|
|
5 |
Hire Personnel |
07APR95 |
13APR95 |
07APR95 |
13APR95 |
0 |
0 |
5 |
5 |
7 |
Prepare |
. |
2 |
0.1.2 |
select h |
|
|
|
3 |
Select Households |
12APR95 |
17APR95 |
17APR95 |
19APR95 |
2 |
2 |
6 |
8 |
8 |
Prepare |
. |
2 |
0.1.3 |
print q |
|
|
|
4 |
Print Questionnaire |
12APR95 |
18APR95 |
13APR95 |
19APR95 |
1 |
1 |
7 |
6 |
9 |
Prepare |
. |
2 |
0.1.1 |
trn per |
|
|
|
3 |
Train Personnel |
17APR95 |
19APR95 |
17APR95 |
19APR95 |
0 |
0 |
8 |
7 |
10 |
Survey |
16 |
1 |
0.2 |
Implement |
|
|
|
18 |
Implement |
20APR95 |
11MAY95 |
20APR95 |
11MAY95 |
0 |
0 |
9 |
9 |
11 |
Implement |
. |
2 |
0.2.0 |
cond sur |
analyze |
|
|
10 |
Conduct Survey |
20APR95 |
03MAY95 |
20APR95 |
03MAY95 |
0 |
0 |
10 |
10 |
12 |
Implement |
. |
2 |
0.2.1 |
analyze |
|
|
|
6 |
Analyze Results |
04MAY95 |
11MAY95 |
04MAY95 |
11MAY95 |
0 |
0 |
11 |
11 |
|
Next, a Gantt chart of the master project schedule is produced with
the subtasks of each project indented under the parent task. To
produce the required indentation, you prefix the Activity description
(saved in the variable id) by a suitable number of blanks using a
simple data step. The following program shows the data step and
the invocation of the GANTT procedure; the resulting Gantt chart is
plotted in Output 2.24.3. Note the precedence constraints between the
two supertasks `Prepare' and `Implement'.
data gant;
length id $26.;
set survout1;
if proj_lev=1 then id=" "||id;
else if proj_lev=2 then id=" "||id;
run;
goptions hpos=80 vpos=43;
title c=black f=swiss 'Conducting a Market Survey';
title2 c=black f=swiss h=1.5 'Project Schedule';
proc gantt graphics data=gant holidata=holidata;
chart / holiday=(hol)
interval=weekday
font=swiss skip=2 height=1.2
nojobnum
compress noextrange
activity=activity succ=(succ1-succ3)
cprec=cyan cmile=magenta
caxis=black cframe=ligr;
id id;
run;
Output 2.24.3: Gantt Chart of Schedule
PROJ_LEV, WBS_CODE, and other project-related variables
can be used to display selected information about specific subprojects,
summary information about subprojects at a given level of the
hierarchy, and more. For example, the following statements display
the summary schedule of the first level subtasks of the Survey
project (Output 2.24.4).
title 'Market Survey';
title2 'Summary Schedule';
proc print data=survout1;
where proj_lev=1;
id activity;
var proj_dur duration e_start--t_float;
run;
Output 2.24.4: Survey Project Summary
Market Survey |
Summary Schedule |
activity |
PROJ_DUR |
duration |
E_START |
E_FINISH |
L_START |
L_FINISH |
T_FLOAT |
Plan |
7 |
6 |
03APR95 |
11APR95 |
03APR95 |
12APR95 |
1 |
Prepare |
8 |
8 |
07APR95 |
19APR95 |
07APR95 |
19APR95 |
0 |
Implement |
16 |
18 |
20APR95 |
11MAY95 |
20APR95 |
11MAY95 |
0 |
|
The variable WBS_CODE in the Schedule data set (see Output 2.24.2)
contains the Work Breakdown structure code defined by the CPM
procedure. This code is defined to be `0.1' for the
subproject `Prepare'. Thus, the values of WBS_CODE for all subtasks of
this subproject are prefixed by `0.1'.
To produce reports for the subproject `Prepare', you can use
a simple WHERE clause to subset the required observations from the
Schedule data set, as shown below.
title 'Market Survey';
title2 'Sub-Project Schedule';
proc print data=survout1;
where substr(WBS_CODE,1,3) = "0.1";
id activity;
var project--activity duration e_start--t_float;
run;
Output 2.24.5: Subproject Schedule
Market Survey |
Sub-Project Schedule |
activity |
project |
PROJ_DUR |
PROJ_LEV |
WBS_CODE |
activity |
duration |
E_START |
E_FINISH |
L_START |
L_FINISH |
T_FLOAT |
Prepare |
Survey |
8 |
1 |
0.1 |
Prepare |
8 |
07APR95 |
19APR95 |
07APR95 |
19APR95 |
0 |
hire per |
Prepare |
. |
2 |
0.1.0 |
hire per |
5 |
07APR95 |
13APR95 |
07APR95 |
13APR95 |
0 |
select h |
Prepare |
. |
2 |
0.1.2 |
select h |
3 |
12APR95 |
17APR95 |
17APR95 |
19APR95 |
2 |
print q |
Prepare |
. |
2 |
0.1.3 |
print q |
4 |
12APR95 |
18APR95 |
13APR95 |
19APR95 |
1 |
trn per |
Prepare |
. |
2 |
0.1.1 |
trn per |
3 |
17APR95 |
19APR95 |
17APR95 |
19APR95 |
0 |
|
In the first invocation of PROC CPM, the Survey project is scheduled
with only a
specification for the project start date. Continuing, this example
shows how you
can impose additional constraints on the master project or on the
individual subprojects.
First, suppose you impose a FINISHBEFORE constraint on the Survey
project by specifying the FBDATE to be May 15, 1995. The following
program schedules the project with a project start and finish
specification. The resulting summary schedule for the subprojects is
shown in Output 2.24.6. Note that the late finish time of the project
is the 12th of May because there is a weekend on the 13th and 14th of
May, 1995.
proc cpm data=survey date='3apr95'd out=survout2
interval=weekday holidata=holidata
fbdate='15may95'd; /* project finish date */
activity activity;
successor succ1-succ3;
duration duration;
id id;
holiday hol;
project project / orderall addwbs;
run;
title 'Market Survey';
title2 'Summary Schedule: FBDATE Option';
proc print data=survout2;
where proj_lev=1; /* First level subprojects */
id activity;
var proj_dur duration e_start--t_float;
run;
Output 2.24.6: Summary Schedule: FBDATE Option
Market Survey |
Summary Schedule: FBDATE Option |
activity |
PROJ_DUR |
duration |
E_START |
E_FINISH |
L_START |
L_FINISH |
T_FLOAT |
Plan |
7 |
6 |
03APR95 |
11APR95 |
04APR95 |
13APR95 |
2 |
Prepare |
8 |
8 |
07APR95 |
19APR95 |
10APR95 |
20APR95 |
1 |
Implement |
16 |
18 |
20APR95 |
11MAY95 |
21APR95 |
12MAY95 |
1 |
|
Note that the procedure computes the backward pass of the schedule
starting from the project finish date. Thus, the critical path is
computed in the context of the entire project. If you want to obtain
individual critical paths for each subproject, use the SEPCRIT option
on the PROJECT statement. You can see the effect of this option
in Output 2.24.7: all the subprojects have T_FLOAT = `0'.
Output 2.24.7: Summary Schedule: FBDATE and SEPCRIT Options
Market Survey |
Summary Schedule: FBDATE and SEPCRIT Options |
activity |
PROJ_DUR |
duration |
E_START |
E_FINISH |
L_START |
L_FINISH |
T_FLOAT |
Plan |
7 |
6 |
03APR95 |
11APR95 |
03APR95 |
11APR95 |
0 |
Prepare |
8 |
8 |
07APR95 |
19APR95 |
07APR95 |
19APR95 |
0 |
Implement |
16 |
18 |
20APR95 |
11MAY95 |
20APR95 |
11MAY95 |
0 |
|
Now, suppose that, in addition to imposing a FINISHBEFORE constraint
on the entire project, the project manager for each subproject
specifies a desired duration for his or her subproject. In the present
example, the variable duration has values `6', `8', and
`18' for the three subprojects. Note that by default
these values are not used in either the backward or forward pass,
even though they may represent desired durations for the corresponding
subprojects.
You can specify the USEPROJDUR option on the PROJECT statement to
indicate that the procedure should use these specified durations
to determine the late finish schedule for each of the subprojects.
In other words, if the USEPROJDUR option is specified, the late
finish for each subproject is constrained to be less than or
equal to
E_START + duration
and this value is used during the backward pass.
The summary schedule resulting from the use of the USEPROJDUR option
is shown in Output 2.24.8. Note the difference in the schedules in
Output 2.24.7 and Output 2.24.8. In Output 2.24.7, the computed project
duration, PROJ_DUR, is used to set an upper bound on
the late finish time of each
subproject, while in Output 2.24.8, the specified project
duration is used for the same purpose. Here, only the
summary schedules are displayed; the effect of the two options on the
subtasks
within each subproject can be seen by displaying the entire schedule
in each case. A Gantt chart of the entire project is displayed in
Output 2.24.9.
Output 2.24.8: Summary Schedule: FBDATE and USEPROJDUR Options
Market Survey |
Summary Schedule: FBDATE and USEPROJDUR Options |
activity |
PROJ_DUR |
duration |
E_START |
E_FINISH |
L_START |
L_FINISH |
T_FLOAT |
Plan |
7 |
6 |
03APR95 |
11APR95 |
31MAR95 |
10APR95 |
-1 |
Prepare |
8 |
8 |
07APR95 |
19APR95 |
07APR95 |
19APR95 |
0 |
Implement |
16 |
18 |
20APR95 |
11MAY95 |
21APR95 |
12MAY95 |
1 |
|
Output 2.24.9: Gantt Chart of Schedule
The project schedule is further affected by the presence of any alignment
dates on the individual activities or subprojects. For example, if the
implementation phase of the project has a deadline of May 10, 1995, you can
specify an alignment date and type variable with the appropriate values
for the subproject `Implement', as follows, and invoke PROC CPM with
the ALIGNDATE and ALIGNTYPE statements, to obtain the new schedule,
displayed in Output 2.24.10.
data survey2;
format aldate date7.;
set survey;
if activity="Implement" then do;
altype="fle";
aldate='10may95'd;
end;
run;
proc cpm data=survey2 date='3apr95'd out=survout5
interval=weekday holidata=holidata
fbdate='15jun95'd;
activity activity;
successor succ1-succ3;
duration duration;
id id;
holiday hol;
project project / orderall addwbs sepcrit useprojdur;
aligntype altype;
aligndate aldate;
run;
title 'Market Survey';
title2 'USEPROJDUR option and Alignment date';
proc print;
where proj_lev=1;
id activity;
var proj_dur duration e_start--t_float;
run;
Output 2.24.10: USEPROJDUR option and Alignment Date
Market Survey |
Summary Schedule: USEPROJDUR option and Alignment date |
activity |
PROJ_DUR |
duration |
E_START |
E_FINISH |
L_START |
L_FINISH |
T_FLOAT |
Plan |
7 |
6 |
03APR95 |
11APR95 |
31MAR95 |
10APR95 |
-1 |
Prepare |
8 |
8 |
07APR95 |
19APR95 |
06APR95 |
18APR95 |
-1 |
Implement |
16 |
18 |
20APR95 |
11MAY95 |
19APR95 |
10MAY95 |
-1 |
|
Copyright © 1999 by SAS Institute Inc., Cary, NC, USA. All rights reserved.