The CPM Procedure |
This example illustrates the effect of resource-driven durations and resource calendars on the schedule of a project involving multiple resources.
In projects that use manpower as a resource, the same activity may require different amounts of work from different people. Also, the work schedules and vacations may differ for each individual person. All of these factors may cause the schedules for the different resources used by the activity to differ from each other.
Consider a software project requiring two resources: a programmer and a tester. A network diagram displaying the activities and their precedence relationships is shown in Output 4.24.1.
Some of the activities in this project have a fixed duration, requiring the same length of time from both resources; others require a different number of days from the programmer and the tester. Further, some activities require only a fraction of the resource; for example, 'Documentation' requires only 20 percent of the programmer’s time for a total of two man-days. The activities in the project, their durations (if fixed) in days, the total work required (if resource-driven) in days, the precedence constraints, and the resource requirements are displayed in Output 4.24.2. There are two observations for some of the activities ('Product Design' and 'Documentation') which require different amounts of work from each resource.
Software Development |
Activity Data Set SOFTWARE |
Activity | act | s1 | s2 | dur | mandays | Programmer | Tester |
---|---|---|---|---|---|---|---|
Plans & Reqts | 1 | 2 | 3 | 2 | . | 1.0 | 1.0 |
Product Design | 2 | 4 | 5 | . | 3 | 1.0 | . |
Product Design | 2 | . | . | . | 1 | . | 1.0 |
Test Plan | 3 | 6 | 7 | 3 | . | . | 1.0 |
Documentation | 4 | 9 | . | . | 2 | 0.2 | . |
Documentation | 4 | . | . | . | 1 | . | 0.5 |
Code | 5 | 8 | . | 10 | . | 0.8 | . |
Test Data | 6 | 8 | . | 5 | . | . | 0.5 |
Test Routines | 7 | 8 | . | 5 | . | . | 0.5 |
Test Product | 8 | 9 | . | 6 | . | 0.5 | 1.0 |
Finish | 9 | . | . | 0 | . | . | . |
The following statements invoke PROC CPM with a WORK= specification on the RESOURCE statement, which identifies (in number of man-days, in this case) the amount of work required from each resource used by an activity. If the WORK variable has a missing value, the activity in that observation is assumed to have a fixed duration. The project is scheduled to start on April 12, 2004, and the activities are assumed to follow a five-day work week. Unlike fixed-duration scheduling, each resource used by an activity could have a different schedule; an activity is assumed to be finished only when all of its resources have finished working on it.
proc cpm data=software out=sftout ressched=rsftout date='12apr04'd interval=weekday resout=rout; act act; succ s1 s2; dur dur; res Programmer Tester / work=mandays rschedid=Activity; id Activity; run;
The individual resource schedules, as well as each activity’s combined schedule, are saved in a Resource Schedule data set, RSFTOUT, requested by the RESSCHED= option on the CPM statement. This output data set (displayed in Output 4.24.3) is very similar to the Schedule data set and contains the activity variable and all the relevant schedule variables (E_START, E_FINISH, L_START, and so forth).
Software Development |
Resource Schedule Data Set RSFTOUT |
A c t i v i t y |
a c t |
R E S O U R C E |
D U R _ T Y P E |
d u r |
m a n d a y s |
R _ R A T E |
E _ S T A R T |
E _ F I N I S H |
L _ S T A R T |
L _ F I N I S H |
---|---|---|---|---|---|---|---|---|---|---|
Plans & Reqts | 1 | 2 | . | . | 12APR04 | 13APR04 | 12APR04 | 13APR04 | ||
Plans & Reqts | 1 | Programmer | FIXED | 2 | . | 1.0 | 12APR04 | 13APR04 | 12APR04 | 13APR04 |
Plans & Reqts | 1 | Tester | FIXED | 2 | . | 1.0 | 12APR04 | 13APR04 | 12APR04 | 13APR04 |
Product Design | 2 | 3 | . | . | 14APR04 | 16APR04 | 14APR04 | 16APR04 | ||
Product Design | 2 | Programmer | RDRIVEN | 3 | 3 | 1.0 | 14APR04 | 16APR04 | 14APR04 | 16APR04 |
Product Design | 2 | Tester | RDRIVEN | 1 | 1 | 1.0 | 14APR04 | 14APR04 | 16APR04 | 16APR04 |
Test Plan | 3 | 3 | . | . | 14APR04 | 16APR04 | 21APR04 | 23APR04 | ||
Test Plan | 3 | Tester | FIXED | 3 | . | 1.0 | 14APR04 | 16APR04 | 21APR04 | 23APR04 |
Documentation | 4 | 10 | . | . | 19APR04 | 30APR04 | 27APR04 | 10MAY04 | ||
Documentation | 4 | Programmer | RDRIVEN | 10 | 2 | 0.2 | 19APR04 | 30APR04 | 27APR04 | 10MAY04 |
Documentation | 4 | Tester | RDRIVEN | 2 | 1 | 0.5 | 19APR04 | 20APR04 | 07MAY04 | 10MAY04 |
Code | 5 | 10 | . | . | 19APR04 | 30APR04 | 19APR04 | 30APR04 | ||
Code | 5 | Programmer | FIXED | 10 | . | 0.8 | 19APR04 | 30APR04 | 19APR04 | 30APR04 |
Test Data | 6 | 5 | . | . | 19APR04 | 23APR04 | 26APR04 | 30APR04 | ||
Test Data | 6 | Tester | FIXED | 5 | . | 0.5 | 19APR04 | 23APR04 | 26APR04 | 30APR04 |
Test Routines | 7 | 5 | . | . | 19APR04 | 23APR04 | 26APR04 | 30APR04 | ||
Test Routines | 7 | Tester | FIXED | 5 | . | 0.5 | 19APR04 | 23APR04 | 26APR04 | 30APR04 |
Test Product | 8 | 6 | . | . | 03MAY04 | 10MAY04 | 03MAY04 | 10MAY04 | ||
Test Product | 8 | Programmer | FIXED | 6 | . | 0.5 | 03MAY04 | 10MAY04 | 03MAY04 | 10MAY04 |
Test Product | 8 | Tester | FIXED | 6 | . | 1.0 | 03MAY04 | 10MAY04 | 03MAY04 | 10MAY04 |
Finish | 9 | 0 | . | . | 11MAY04 | 11MAY04 | 11MAY04 | 11MAY04 |
For each activity in the project, the Resource Schedule data set contains the schedule for the entire activity as well as the schedule for each resource used by the activity. The variable RESOURCE identifies the name of the resource to which the observation refers and has missing values for observations that refer to the entire activity’s schedule. The value of the variable DUR_TYPE indicates whether the resource drives the activity’s duration ('RDRIVEN') or not ('FIXED').
The DURATION variable, dur, indicates the duration of the activity for the resource identified in that observation. For resources that are of the driving type, the WORK variable, mandays, shows the total amount of work (in units of the INTERVAL parameter) required by the resource for the activity in that observation. The variable R_RATE shows the rate of usage of the resource for the relevant activity. For driving resources, the variable dur is computed as (mandays / R_RATE). Thus, for the Activity, 'Documentation', the programmer requires 10 days to complete 2 man-days of work at a rate of 20 percent per day, while the tester works at a rate of 50 percent requiring 2 days to complete 1 man-day of work.
pattern1 c=green v=s; /* duration of a non-critical activity */ pattern2 c=green v=e; /* slack time for a noncrit. activity */ pattern3 c=red v=s; /* duration of a critical activity */ pattern4 c=magenta v=e; /* slack time for a supercrit. activity */ pattern5 c=magenta v=s; /* duration of a supercrit. activity */ pattern6 c=cyan v=s; /* actual duration of an activity */ pattern7 c=black v=e; /* break due to a holiday */ pattern8 c=blue v=s; /* resource schedule of activity */ pattern9 c=brown v=s; /* baseline schedule of activity */ title h=2 'Software Development'; title2 h=1.5 'Project Schedule';
A Gantt chart of the schedules for each resource is plotted in Output 4.24.4.
Software Development |
Resource Usage Data Set ROUT |
Obs | _TIME_ | EProgrammer | LProgrammer | ETester | LTester |
---|---|---|---|---|---|
1 | 12APR04 | 1.0 | 1.0 | 1.0 | 1.0 |
2 | 13APR04 | 1.0 | 1.0 | 1.0 | 1.0 |
3 | 14APR04 | 1.0 | 1.0 | 2.0 | 0.0 |
4 | 15APR04 | 1.0 | 1.0 | 1.0 | 0.0 |
5 | 16APR04 | 1.0 | 1.0 | 1.0 | 1.0 |
6 | 19APR04 | 1.0 | 0.8 | 1.5 | 0.0 |
7 | 20APR04 | 1.0 | 0.8 | 1.5 | 0.0 |
8 | 21APR04 | 1.0 | 0.8 | 1.0 | 1.0 |
9 | 22APR04 | 1.0 | 0.8 | 1.0 | 1.0 |
10 | 23APR04 | 1.0 | 0.8 | 1.0 | 1.0 |
11 | 26APR04 | 1.0 | 0.8 | 0.0 | 1.0 |
12 | 27APR04 | 1.0 | 1.0 | 0.0 | 1.0 |
13 | 28APR04 | 1.0 | 1.0 | 0.0 | 1.0 |
14 | 29APR04 | 1.0 | 1.0 | 0.0 | 1.0 |
15 | 30APR04 | 1.0 | 1.0 | 0.0 | 1.0 |
16 | 03MAY04 | 0.5 | 0.7 | 1.0 | 1.0 |
17 | 04MAY04 | 0.5 | 0.7 | 1.0 | 1.0 |
18 | 05MAY04 | 0.5 | 0.7 | 1.0 | 1.0 |
19 | 06MAY04 | 0.5 | 0.7 | 1.0 | 1.0 |
20 | 07MAY04 | 0.5 | 0.7 | 1.0 | 1.5 |
21 | 10MAY04 | 0.5 | 0.7 | 1.0 | 1.5 |
22 | 11MAY04 | 0.0 | 0.0 | 0.0 | 0.0 |
Suppose now that you have only one tester and one programmer. You can determine a resource-constrained schedule using PROC CPM (as in the fixed duration case) by specifying a resource availability data set, RESIN (Output 4.24.6).
proc cpm data=software resin=resin out=sftout1 resout=rout1 rsched=rsftout1 date='12apr04'd interval=weekday; act act; succ s1 s2; dur dur; res Programmer Tester / work=mandays addcal obstype=otype period=per rschedid=Activity; id Activity; run;
Software Development |
Resource Constrained Schedule: Common Resource Calendar |
Activity | act | _CAL_ | RESOURCE | DUR_TYPE | dur | mandays | R_RATE | S_START | S_FINISH | E_START | E_FINISH | L_START | L_FINISH |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Plans & Reqts | 1 | 0 | 2 | . | . | 12APR04 | 13APR04 | 12APR04 | 13APR04 | 12APR04 | 13APR04 | ||
Plans & Reqts | 1 | 0 | Programmer | FIXED | 2 | . | 1.0 | 12APR04 | 13APR04 | 12APR04 | 13APR04 | 12APR04 | 13APR04 |
Plans & Reqts | 1 | 0 | Tester | FIXED | 2 | . | 1.0 | 12APR04 | 13APR04 | 12APR04 | 13APR04 | 12APR04 | 13APR04 |
Product Design | 2 | 0 | 3 | . | . | 14APR04 | 16APR04 | 14APR04 | 16APR04 | 14APR04 | 16APR04 | ||
Product Design | 2 | 0 | Programmer | RDRIVEN | 3 | 3 | 1.0 | 14APR04 | 16APR04 | 14APR04 | 16APR04 | 14APR04 | 16APR04 |
Product Design | 2 | 0 | Tester | RDRIVEN | 1 | 1 | 1.0 | 14APR04 | 14APR04 | 14APR04 | 14APR04 | 16APR04 | 16APR04 |
Test Plan | 3 | 0 | 3 | . | . | 15APR04 | 19APR04 | 14APR04 | 16APR04 | 21APR04 | 23APR04 | ||
Test Plan | 3 | 0 | Tester | FIXED | 3 | . | 1.0 | 15APR04 | 19APR04 | 14APR04 | 16APR04 | 21APR04 | 23APR04 |
Documentation | 4 | 0 | 10 | . | . | 27APR04 | 10MAY04 | 19APR04 | 30APR04 | 27APR04 | 10MAY04 | ||
Documentation | 4 | 0 | Programmer | RDRIVEN | 10 | 2 | 0.2 | 27APR04 | 10MAY04 | 19APR04 | 30APR04 | 27APR04 | 10MAY04 |
Documentation | 4 | 0 | Tester | RDRIVEN | 2 | 1 | 0.5 | 27APR04 | 28APR04 | 19APR04 | 20APR04 | 07MAY04 | 10MAY04 |
Code | 5 | 0 | 10 | . | . | 19APR04 | 30APR04 | 19APR04 | 30APR04 | 19APR04 | 30APR04 | ||
Code | 5 | 0 | Programmer | FIXED | 10 | . | 0.8 | 19APR04 | 30APR04 | 19APR04 | 30APR04 | 19APR04 | 30APR04 |
Test Data | 6 | 0 | 5 | . | . | 20APR04 | 26APR04 | 19APR04 | 23APR04 | 26APR04 | 30APR04 | ||
Test Data | 6 | 0 | Tester | FIXED | 5 | . | 0.5 | 20APR04 | 26APR04 | 19APR04 | 23APR04 | 26APR04 | 30APR04 |
Test Routines | 7 | 0 | 5 | . | . | 20APR04 | 26APR04 | 19APR04 | 23APR04 | 26APR04 | 30APR04 | ||
Test Routines | 7 | 0 | Tester | FIXED | 5 | . | 0.5 | 20APR04 | 26APR04 | 19APR04 | 23APR04 | 26APR04 | 30APR04 |
Test Product | 8 | 0 | 6 | . | . | 03MAY04 | 10MAY04 | 03MAY04 | 10MAY04 | 03MAY04 | 10MAY04 | ||
Test Product | 8 | 0 | Programmer | FIXED | 6 | . | 0.5 | 03MAY04 | 10MAY04 | 03MAY04 | 10MAY04 | 03MAY04 | 10MAY04 |
Test Product | 8 | 0 | Tester | FIXED | 6 | . | 1.0 | 03MAY04 | 10MAY04 | 03MAY04 | 10MAY04 | 03MAY04 | 10MAY04 |
Finish | 9 | 0 | 0 | . | . | 11MAY04 | 11MAY04 | 11MAY04 | 11MAY04 | 11MAY04 | 11MAY04 |
Now suppose that the tester switches to part-time employment, working only four days a week. Thus, the two resources have different calendars. To determine the effect this change has on the project schedule, define a calendar data set identifying calendar '1' as having a holiday on Friday (see Output 4.24.9). In a new resource availability data set (also displayed in Output 4.24.9), associate calendar '1' with the resource Tester and calendar '0' with the resource Programmer. '0' refers to the default calendar, which is the weekday calendar for this project (since INTERVAL = WEEKDAY).
Resource Data Set RESIN2 |
Obs | per | otype | Programmer | Tester |
---|---|---|---|---|
1 | . | calendar | 0 | 1 |
2 | 12APR04 | reslevel | 1 | 1 |
Next, invoke PROC CPM, as shown in the following statements, with the Activity, Resource, and Calendar data sets to obtain the revised schedule, plotted in Output 4.24.10. The project is delayed by two days because of the TESTER’s shorter work week, which is illustrated by the longer holiday breaks in the TESTER’s schedule bars. The new resource constrained schedule is displayed in Output 4.24.11.
proc cpm data=software resin=resin2 caledata=calendar out=sftout2 rsched=rsftout2 resout=rout2 date='12apr04'd interval=weekday; act act; succ s1 s2; dur dur; res Programmer Tester / work=mandays addcal obstype=otype period=per rschedid=Activity; id Activity; run;
Software Development |
Resource Constrained Schedule: Multiple Resource Calendars |
Activity | act | _CAL_ | RESOURCE | DUR_TYPE | dur | mandays | R_RATE | S_START | S_FINISH | E_START | E_FINISH | L_START | L_FINISH |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Plans & Reqts | 1 | 0 | 2 | . | . | 12APR04 | 13APR04 | 12APR04 | 13APR04 | 12APR04 | 13APR04 | ||
Plans & Reqts | 1 | 0 | Programmer | FIXED | 2 | . | 1.0 | 12APR04 | 13APR04 | 12APR04 | 13APR04 | 12APR04 | 13APR04 |
Plans & Reqts | 1 | 1 | Tester | FIXED | 2 | . | 1.0 | 12APR04 | 13APR04 | 12APR04 | 13APR04 | 12APR04 | 13APR04 |
Product Design | 2 | 0 | 3 | . | . | 14APR04 | 16APR04 | 14APR04 | 16APR04 | 14APR04 | 16APR04 | ||
Product Design | 2 | 0 | Programmer | RDRIVEN | 3 | 3 | 1.0 | 14APR04 | 16APR04 | 14APR04 | 16APR04 | 14APR04 | 16APR04 |
Product Design | 2 | 1 | Tester | RDRIVEN | 1 | 1 | 1.0 | 14APR04 | 14APR04 | 14APR04 | 14APR04 | 15APR04 | 15APR04 |
Test Plan | 3 | 0 | 3 | . | . | 15APR04 | 20APR04 | 14APR04 | 19APR04 | 19APR04 | 21APR04 | ||
Test Plan | 3 | 1 | Tester | FIXED | 3 | . | 1.0 | 15APR04 | 20APR04 | 14APR04 | 19APR04 | 19APR04 | 21APR04 |
Documentation | 4 | 0 | 10 | . | . | 29APR04 | 12MAY04 | 19APR04 | 30APR04 | 28APR04 | 11MAY04 | ||
Documentation | 4 | 0 | Programmer | RDRIVEN | 10 | 2 | 0.2 | 29APR04 | 12MAY04 | 19APR04 | 30APR04 | 28APR04 | 11MAY04 |
Documentation | 4 | 1 | Tester | RDRIVEN | 2 | 1 | 0.5 | 29APR04 | 03MAY04 | 19APR04 | 20APR04 | 10MAY04 | 11MAY04 |
Code | 5 | 0 | 10 | . | . | 19APR04 | 30APR04 | 19APR04 | 30APR04 | 19APR04 | 30APR04 | ||
Code | 5 | 0 | Programmer | FIXED | 10 | . | 0.8 | 19APR04 | 30APR04 | 19APR04 | 30APR04 | 19APR04 | 30APR04 |
Test Data | 6 | 0 | 5 | . | . | 21APR04 | 28APR04 | 20APR04 | 27APR04 | 22APR04 | 30APR04 | ||
Test Data | 6 | 1 | Tester | FIXED | 5 | . | 0.5 | 21APR04 | 28APR04 | 20APR04 | 27APR04 | 22APR04 | 29APR04 |
Test Routines | 7 | 0 | 5 | . | . | 21APR04 | 28APR04 | 20APR04 | 27APR04 | 22APR04 | 30APR04 | ||
Test Routines | 7 | 1 | Tester | FIXED | 5 | . | 0.5 | 21APR04 | 28APR04 | 20APR04 | 27APR04 | 22APR04 | 29APR04 |
Test Product | 8 | 0 | 6 | . | . | 04MAY04 | 12MAY04 | 03MAY04 | 11MAY04 | 03MAY04 | 11MAY04 | ||
Test Product | 8 | 0 | Programmer | FIXED | 6 | . | 0.5 | 04MAY04 | 11MAY04 | 03MAY04 | 10MAY04 | 04MAY04 | 11MAY04 |
Test Product | 8 | 1 | Tester | FIXED | 6 | . | 1.0 | 04MAY04 | 12MAY04 | 03MAY04 | 11MAY04 | 03MAY04 | 11MAY04 |
Finish | 9 | 0 | 0 | . | . | 13MAY04 | 13MAY04 | 12MAY04 | 12MAY04 | 12MAY04 | 12MAY04 |
Copyright © SAS Institute, Inc. All Rights Reserved.