Resources

Factory Expansion Project

 /****************************************************************/
 /*          S A S   S A M P L E   L I B R A R Y                 */
 /*                                                              */
 /*    NAME: PMEX02                                              */
 /*   TITLE: Factory Expansion Project                           */
 /* PRODUCT: OR                                                  */
 /*  SYSTEM: ALL                                                 */
 /*    KEYS: CPM                                                 */
 /*   PROCS: CPM, PRINT, NETDRAW, GANTT, SORT, GPLOT             */
 /*    DATA:                                                     */
 /*                                                              */
 /* SUPPORT:                             UPDATE:                 */
 /*     REF: Example 2 of Project Management Examples Book       */
 /*    MISC: Burman, Precedence Networks for Project Planning    */
 /*                  and Control                                 */
 /****************************************************************/

goptions border hpos=80 vpos=43
         fby=swiss
         ftitle=swiss
         htitle=2
         ftext=swiss
         htext=1.5;

pattern1 v=solid c=blue;
pattern2 v=e c=blue;
pattern3 v=solid c=red;
pattern4 v=e c=red;
pattern5 v=x2 c=red;
pattern6 v=solid c=green;
pattern7 v=e c=magenta;
pattern8 v=solid c=magenta;
pattern9 v=x1 c=cyan;

title 'Factory Expansion Project';

data factdata;
format id $28.;
input act s1 s2 s3 s4 s5 s6 s7 s8 dur id &;
cards;
 1   3   .   .   .   .   .   .   .    3  Level site
 2   1   .   .   .   .   .   .   .    1  Demolish paint store
 3  11   5   5   4   4   .   .   .    6  Excavate foundations
 4  10  10   7   7   .   .   .   .   10  Cast foundations
 5  17  18  10  10  20  21  23  24   20  Cast plinths in new area
 6  26   .   .   .   .   .   .   .    4  Cast plinths for presses
 7   8   8   .   .   .   .   .   .    6  Erect steel structure
 8  29   9   .   .   .   .   .   .    9  Clad roof and walls
 9  17  18  20  21  23  24   .   .    2  Demolish old walls
10  17  18  20  21  23  24   .   .   10  Cast floor
11  10   .   .   .   .   .   .   .    4  Lay underground cables
12  26   .   .   .   .   .   .   .    6  Relocate services
13  15   .   .   .   .   .   .   .    3  Prepare opening
14  15   .   .   .   .   .   .   .    5  Order roller door
15   .   .   .   .   .   .   .   .    2  Install roller door
16  17   .   .   .   .   .   .   .    5  Order 2 new benches
17  18   .   .   .   .   .   .   .    1  Install new benches
18  27  28  31   .   .   .   .   .    4  Re-site 4 old benches
19  20   .   .   .   .   .   .   .    5  Order 4 new machines
20  21   .   .   .   .   .   .   .    6  Install new machines
21  27  28  30   .   .   .   .   .   16  Re-site 8 old machines
22  23   .   .   .   .   .   .   .    5  Order 2 new small presses
23  24   .   .   .   .   .   .   .    4  Install new small presses
24   6  12   .   .   .   .   .   .   12  Re-site 4 old small presses
25  26   .   .   .   .   .   .   .    5  Order 2 new large presses
26  31   .   .   .   .   .   .   .    9  Install new large presses
27   .   .   .   .   .   .   .   .    2  Erect finished store walls
28   .   .   .   .   .   .   .   .    4  Erect finished store racks
29  17  18  20  21  23   .   .   .    3  Install lighting in new area
30  31   .   .   .   .   .   .   .    2  Extend paint section
31   .   .   .   .   .   .   .   .    2  Paint aisles
;

proc cpm data=factdata out=factout
date='01nov90'd finishbefore;
activity act;
id id;
duration dur;
successor s1-s8;
run;

proc sort data=factout;
by e_start;
run;

title2 'Initial Schedule';

proc print data=factout noobs;
var id e_start e_finish l_start l_finish t_float;
run;

title2 'Network Indicating Critical Activities';

pattern1 v=e;
pattern2 c=red;

proc netdraw data=factout graphics;
actnet/activity=act successor=(s1-s8) id=(id)
compress separatearcs font=simplex carcs=blue;
run;

proc netdraw data=factout graphics;
actnet/activity=act successor=(s1-s8) id=(id)
separatearcs carcs=blue;
run;

pattern1 v=s;
pattern2 c=blue;


data lags;
input act l1 $ l2 $ l3 $ l4 $ l5 $ l6 $ l7 $ l8 $;
cards;
3   .     FF_10  SS_3   FF_5   SS_3    .      .      .
4  FF_5   SS_5   FF_13  SS_15   .      .      .      .
5  FS_10  FS_10  FF_5   SS_10  SS_26  SS_26  SS_16  SS_16
6  FS_10   .      .      .      .      .      .      .
7  FF_3   SS_2    .      .      .      .      .      .
10  .      .     SS_8   SS_8   SS_8   SS_3    .      .
14 FS_5    .      .      .      .      .      .      .
16 FS_14   .      .      .      .      .      .      .
19 FS_35   .      .      .      .      .      .      .
20 FF_12   .      .      .      .      .      .      .
22 FS_28   .      .      .      .      .      .      .
23 FF_9    .      .      .      .      .      .      .
25 FS_49   .      .      .      .      .      .      .
 ;

data factdata;
merge factdata lags;
by act;
run;

proc cpm data=factdata out=factout1
date='01nov90'd finishbefore;
activity act;
id id;
duration dur;
successor s1-s8/lag=(l1-l8);
run;

proc sort data=factout1;
by e_start;
run;

title2 'Schedule with Non-Standard Relationships';

proc print data=factout1 noobs;
var id e_start e_finish l_start l_finish t_float;
run;

 /* Resource Codes:   C  Concrete crew                    */
 /*                   D  Excavation and demolition crew   */
 /*                   E  Electrical crew                  */
 /*                   F  Machine installation crew        */
 /*                   O  Own staff                        */
 /*                   P  Partitions and cladding crew     */
 /*                   R  Rigging crew                     */


data resource;
input c d e f o p r;
cards;
. 1 . . . . .
. 1 . . . . .
. 1 . . . . .
1 . . . . . .
1 . . . . . .
1 . . . . . .
. . . . . . 1
. . . . . 1 .
. 1 . . . . .
1 . . . . . .
. . 1 . . . .
. . 1 . . . .
. . . . . . 1
. . . . 1 . .
. . . . . . 1
. . . . 1 . .
. . . 1 . . .
. . . 1 . . .
. . . . 1 . .
. . . 1 . . .
. . . 1 . . .
. . . . 1 . .
. . . 1 . . .
. . . 1 . . .
. . . . 1 . .
. . . 1 . . .
. . . . . 1 .
. . . . . 1 .
. . 1 . . . .
. . . . . 1 .
. . . . 1 . .
;

data factdata;
merge factdata resource;
run;


proc cpm data=factdata out=factout2
date='01nov90'd finishbefore
resout=fresusg;
activity act;
id id;
duration dur;
successor s1-s8/lag=(l1-l8);
resource c d e f o p r;
run;



title2 'Comparison of Machine Installation Crew Usage';

symbol1 i=steplj w=2 l=1;
symbol2 i=steplj w=2 l=2;

legend1 label=('Schedule Followed')
        value=('Early Start' 'Late Start')
        across=2;

axis1 label=('Crews Required');
axis2 label=none;

proc gplot data=fresusg;
plot (ef lf) * _time_ / overlay
                        vaxis=axis1
                        haxis=axis2
                        legend=legend1;
run;


data freslvl;
input obstype $ period c d e f o p r;
cards;
restype  . 1 1 1 1 1 1 1
reslevel 0 1 1 1 1 1 1 1
;

proc cpm data=factdata out=factout3
date='01nov90'd finishbefore
resout=fresusg1 resin=freslvl;
activity act;
id id;
duration dur;
successor s1-s8/lag=(l1-l8);
resource c d e f o p r/obstype=obstype
period=period delay=0 infeasdiagnostic
delayanalysis;
run;

title2 'Schedule with Limited Resources';

proc print data=fresusg1;
var _time_ rc ac rd ad re ae rf af ro ao rp ap rr ar;
run;

proc print data=factout3;
     var id s_start s_finish r_delay delay_r suppl_r;
run;

data freslvl1;
input obstype $ period c d e f o p r;
cards;
suplevel . 1 . . 1 . 1 .
;

data freslvl1;
set freslvl freslvl1;
run;

proc cpm data=factdata out=factout4
date='01nov90'd finishbefore
resout=fresusg2 resin=freslvl1;
activity act;
id id;
duration dur;
successor s1-s8/lag=(l1-l8);
resource c d e f o p r/obstype=obstype
period=period delay=0;
run;

proc sort data=factout4;
by s_start;
run;

title2 'Schedule with Supplementary Resources';

proc gantt graphics data=factout4;
chart/compress nojobnum;
id id;
run;

symbol1 i=steplj w=2 l=1;
symbol2 i=steplj w=2 l=2;
symbol3 i=steplj w=4 l=3;

title2 'Comparison of Machine Installation Crew Usage';

legend2 label=('Schedule Followed')
        value=('Early Start' 'Late Start' 'Constrained')
        across=2;

proc gplot data=fresusg2;
plot (ef lf rf) * _time_ / overlay
                           vref=1
                           lvref=4
                           vaxis=axis1
                           haxis=axis2
                           legend=legend2;
run;


title2 'Comparison of Resource Usage';

proc print data=fresusg2;
var ec lc rc ac ef lf rf af ep lp rp ap;
run;


data freslvl2;
input obstype $ period res_name $ c d e f o p r;
cards;
altrate . c 1 1 . . . . .
altprty . c 1 2 . . . . .
altrate . f . . 1 1 1 . .
altprty . f . . 2 1 3 . .
altrate . p . . . . 1 1 1
altprty . p . . . . 3 1 2
;

data freslvl2;
     set freslvl freslvl2;
run;

data fdata;
     set factdata;
     minsgmt=1;
run;

proc cpm data=fdata out=factout5
date='01nov90'd finishbefore
resout=fresusg3 resin=freslvl2;
activity act;
id id;
duration dur;
successor s1-s8/lag=(l1-l8);
resource c d e f o p r/obstype=obstype
noe_start nol_start minsegmtdur=minsgmt
period=period delay=0 resid=res_name;
run;

proc print data=factout5;
var id segmt_no dur c d e f o p r uc ud ue uf uo up ur;
run;

data dummy;
     set factout5;
     retain tstart;
     if segmt_no = . then tstart=s_start;
run;

proc sort data=dummy;
     by tstart;
run;

title2 'Schedule with Alternate Resources';

proc gantt graphics data=dummy;
chart/compress nojobnum nolegend;
id id;
run;

data dummy (drop=segmt_no) ;
     set dummy;
     if uc=1 then resource='C';
     if ud=1 then resource='D';
     if ue=1 then resource='E';
     if uf=1 then resource='F';
     if uo=1 then resource='O';
     if up=1 then resource='P';
     if ur=1 then resource='R';
     if resource='' then delete;
run;

proc sort data=dummy;
     by resource;
run;

title2 'Resource-Specific Schedule';

proc gantt graphics data=dummy;
chart/compress nojobnum nolegend dupok skip=2;
by resource;
id id;
run;