Resource-Constrained Project Scheduling Problem
/***************************************************************/
/* */
/* S A S S A M P L E L I B R A R Y */
/* */
/* NAME: clpe15 */
/* TITLE: Resource-Constrained Project Scheduling Problem */
/* with Calendars (clpe15) */
/* PRODUCT: OR */
/* SYSTEM: ALL */
/* KEYS: OR */
/* PROCS: CLP */
/* DATA: */
/* */
/* SUPPORT: UPDATE: */
/* REF: */
/* MISC: Example 15 from the CLP Procedure chapter of the */
/* Constraint Programming book. */
/* */
/***************************************************************/
data StartTime;
input Start1-Start14 S T _TYPE_ $ _RHS_;
datalines;
0 0 0 0 0 0 0 0 0 0 0 0 . . . 10 LOWERBD .
40 40 40 40 40 40 40 40 40 40 40 40 . . . 40 UPPERBD .
. . . . . . . . . . . . 5 6 0 . FIXED .
;
proc print data=StartTime;
run;
data Precedence;
input S Start1-Start12 T _TYPE_ $ _RHS_;
datalines;
-1 1 . . . . . . . . . . . . GE 0
-1 . 1 . . . . . . . . . . . GE 0
-1 . . 1 . . . . . . . . . . GE 0
-1 . . . . . 1 . . . . . . . GE 0
-1 . . . . . . 1 . . . . . . GE 0
. -1 . . 1 . . . . . . . . . GE 1
. . -1 . . 1 . . . . . . . . GE 2
. . . -1 . . . . . . . . . 1 GE 2
. . . . -1 . . . . . . . . 1 GE 6
. . . . . -1 . . . . . . . 1 GE 3
. . . . . . -1 . . . . . 1 . GE 6
. . . . . . . -1 1 . . . . . GE 1
. . . . . . . -1 . 1 . . . . GE 1
. . . . . . . -1 . . 1 . . . GE 1
. . . . . . . . -1 . . 1 . . GE 3
. . . . . . . . . -1 . . 1 . GE 3
. . . . . . . . . . -1 . 1 . GE 4
. . . . . . . . . . . -1 1 . GE 2
. . . . . . . . . . . . -1 1 GE 4
;
proc print data=Precedence;
run;
data Objective;
input T _TYPE_ $ _RHS_;
datalines;
1 MIN .
;
proc print data=Objective;
run;
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;
data durdata;
input Dur1-Dur12;
datalines;
1 2 2 6 3 6 1 3 3 4 2 4
;
data demdata;
input Dem1-Dem12;
datalines;
4 2 3 3 2 3 1 2 2 1 2 2
;
data SchedOut;
set outdata;
set durdata;
set demdata;
array st{12} Start1-Start12;
array dur{12} Dur1-Dur12;
array dem{12} Dem1-Dem12;
do tid = 1 to 12;
Task=tid;
Start=st{tid};
Duration=dur{tid};
End=Start + Duration;
Demand=Dem{tid};
output;
end;
keep Task Start Duration End Demand;
run;
proc print data=SchedOut noobs;
run;
proc print data=SchedOut noobs;
run;
data resin;
input per obstype $ demand;
datalines;
0 RESLEVEL 100
;
data indata;
set schedout;
atype = 'MS';
adate = start;
;
proc cpm data=indata out=out resout=resout resin=resin;
aligntype atype;
aligndate adate;
activity task;
duration duration;
resource demand / per=per obstype=obstype;
run;
%annomac;
proc sql noprint;
select count(*) into :cnt from schedout;
select max(end) into :ms from schedout;
select min(start) into :pi from schedout;
quit;
data anno;
%dclanno; /* set length and type for annotate variables */
%system(2,2,4); /* define annotate reference system */
set resout(where=(_time_ < &ms.)) end=lastobs;
length lab $16;
length TEXT $27;
x1 = _time_;
x2 = x1 +1;
y1 = &cnt + 0.5;
y2 = y1 - rdemand;
%bar(x1,y1,x2,y2,blue,0,l1);
if lastobs then do;
do i = 1 to &cnt.-1;
c = put(i,z2.);
%label(14.2, y1 - i, c, red, 0, 0, 0.8, 'arial', 0);
end;
%label(14.2, y1 - 0.4 ,"RES", red,0, 0, 0.8, 'arial', 0);
%label(14.2, y1, "LEVL", red,0, 0, 0.8, 'arial', 0);
y2 = y1 -8;
%line(0, y2, 5, y2, red, 1, 3);
y2 = y2 + 4;
%draw(5, y2, red, 1, 3);
%draw(6, y2, red, 1, 3);
y2 = y2 + 4;
%draw(6, y2, red, 1, 3);
%draw(7, y2, red, 1, 3);
y2 = y2 - 8;
%draw(7, y2, red, 1, 3);
%draw(14, y2, red, 1, 3);
end;
run;
goptions vpos=30 ftext='arial';
proc gantt data=schedout annotate=anno;
chart / s_start=start s_finish=end maxdate=15
pcompress
nolegend nojobnum height=0.8;
id task demand;
run;
/***************************************************************/
/* */
/* S A S S A M P L E L I B R A R Y */
/* */
/* NAME: clpe15 (part b) */
/* TITLE: Resource-Constrained Project Scheduling Problem */
/* with Optional Tasks */
/* PRODUCT: OR */
/* SYSTEM: ALL */
/* KEYS: OR */
/* PROCS: CLP */
/* DATA: */
/* */
/* SUPPORT: UPDATE: */
/* REF: */
/* MISC: Example 9b from the CLP Procedure chapter of the */
/* Constraint Programming book. */
/* */
/***************************************************************/
data StartTime2;
input Start1-Start14 S T _TYPE_ $ _RHS_;
datalines;
0 0 0 0 0 0 0 0 0 0 0 0 . . . . LOWERBD .
12 12 12 12 12 12 12 12 12 12 12 12 . . . . UPPERBD .
. . . . . . . . . . . . 5 6 0 12 FIXED .
;
proc print data=StartTime2;
run;
data Precedence;
input S Start1-Start12 T _TYPE_ $ _RHS_;
datalines;
-1 1 . . . . . . . . . . . . GE 0
-1 . 1 . . . . . . . . . . . GE 0
-1 . . 1 . . . . . . . . . . GE 0
-1 . . . . . 1 . . . . . . . GE 0
-1 . . . . . . 1 . . . . . . GE 0
. -1 . . 1 . . . . . . . . . GE 1
. . -1 . . 1 . . . . . . . . GE 2
. . . -1 . . . . . . . . . 1 GE 2
. . . . -1 . . . . . . . . 1 GE 6
. . . . . -1 . . . . . . . 1 GE 3
. . . . . . -1 . . . . . 1 . GE 6
. . . . . . . -1 1 . . . . . GE 1
. . . . . . . -1 . 1 . . . . GE 1
. . . . . . . -1 . . 1 . . . GE 1
. . . . . . . . -1 . . 1 . . GE 3
. . . . . . . . . -1 . . 1 . GE 3
. . . . . . . . . . -1 . 1 . GE 4
. . . . . . . . . . . -1 1 . GE 2
. . . . . . . . . . . . -1 1 GE 4
;
data Demand;
input Demand1-Demand14 _TYPE_ $ _RHS_;
datalines;
0 0 0 0 0 . . . . . . . . . LOWERBD .
4 2 3 3 2 . . . . . . . . . UPPERBD .
. . . . . 2 1 1 2 1 2 2 4 8 FIXED .
;
proc print data=Demand;
run;
data Binary;
input X1-X3 _TYPE_ $ _RHS_;
datalines;
1 1 1 BINARY .
;
proc print data=Binary;
run;
data Usage;
input Demand1-Demand5 X1-X3 _TYPE_ $ _RHS_;
datalines;
1 . . . . 4 . . EQ 4
. 1 . . . . 2 . EQ 2
. . 1 . . . . 3 EQ 3
. . . 1 . 3 . . EQ 3
. . . . 1 . 2 . EQ 2
;
proc print data=Usage;
run;
data Objective2;
input X1-X3 _TYPE_ $ _RHS_;
datalines;
15 12 5 MIN .
;
proc print data=Objective2;
run;
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;
data durdata;
input Dur1-Dur12;
datalines;
1 2 2 6 3 6 1 3 3 4 2 4
;
data SchedOut2;
set outdata2;
set durdata;
array st{12} Start1-Start12;
array dur{12} Dur1-Dur12;
array dem{12} Demand1-Demand12;
do tid = 1 to 12;
Task=tid;
Start=st{tid};
Duration=dur{tid};
End=Start + Duration;
Demand=dem{tid};
if Demand > 0 then output;
end;
keep Task Start Duration End Demand;
run;
proc print data=SchedOut2 noobs;
run;