/***********************************************************************************
* This program is taken from the following book. If using please cite it as: *
* Emrouznejad, A. and W. Ho (2012). Applied Operations Research with SAS, *
* CRC Press: Taylor Francis Ltd, ISBN: 9781439841303. *
* For details please visit: http://www.sas-or.com. *
************************************************************************************/
* A SAS procedure for SMT placement machines or the component sequencing problem;
%let _title=’Example 7.3: SMT placement machines or the component sequencing problem’;
%let _dataC=’c:/sasor/Data7_3_C.txt’;
%let _dataF=’c:/sasor/Data7_3_F.txt’;
%let _nFeeder=4;
%let _nCompon=4;
%let _outprimal= outprimal;
%let _outdual= outdual;
%let _outtable= outtable;
option nodate;
* The data handling macro;
%macro data;
* Import text tab delimited data file to SAS data file;
proc import
datafile=&_dataC
out=dataC
dbms=tab
replace;
getnames=yes;
run;
proc import
datafile=&_dataF
out=dataF
dbms=tab
replace;
getnames=yes;
run;
%mend data;
* The model building macro;
%macro model;
* Starting OPTMODEL Procedure;
proc optmodel;
* Define sets;
set COMP=0..&_nCompon;
set Feed=0..&_nFeeder;
* Define variables;
var u{COMP} integer >=0;
var x{COMP,COMP} binary >=0 ;
var z;
* Define parameters;
number d{COMP,COMP};
number cx {COMP};
number cy {COMP};
number type {COMP};
number fx {FEED};
number fy {FEED};
number randfeeder {FEED};
number d1;
number d2;
number Distance{COMP,FEED};
number ds2{COMP,FEED};
* Load component data;
read data Datac into [_N_] type[_N_]=col(‘type’);
read data Datac into [_N_] cx[_N_]=col(‘cx’);
read data Datac into [_N_] cy[_N_]=col(‘cy’);
* Load feeder data;
read data Dataf into [_N_] fx[_N_]=col(‘fx’);
read data Dataf into [_N_] fy[_N_]=col(‘fy’);
read data Dataf into [_N_] randfeeder[_N_]=col(‘randfeeder’);
cx[0]=0; cy[0]=0; fx[0]=0; fy[0]=0;
for {i in FEED, j in COMP}
do;
if (i ne 0 & j ne 0)
then do; d1=(cx[i]-fx[j])**2; d2=(cy[i]-fy[j])**2; end;
else if (i=0 & j=0)
then do; d1=0; d2=0; end;
else if (i=0)
then do; d1=(cx[j]**2); d2=(cy[j]**2); end;
else if (j=0)
then do; d1=(fx[i]**2); d2=(fy[i]**2); end;
Distance[i,j]=round(sqrt( d1+d2),0.000001);
end;
print Distance;
for {i in FEED, j in COMP}
do;
if (i=j) then ds2[i,j]=0;
else if i=0 then ds2[j,i]=Distance[randfeeder[j],0]+Distance[j,randfeeder[j]];
else if j=0 then ds2[j,i]=Distance[j,i];
else ds2[j,i]=Distance[j,randfeeder[j]]+Distance[i,randfeeder[j]];
end;
* Define objective function ;
min obj = z;
* Define constrains;
con Objective: z= sum{i in FEED, j in COMP} ds2[j,i]*x[i,j];
con component_immediately_before1 {i in FEED}: sum{j in COMP: i ne j} x[j,i]=1;
con component_immediately_before2 {j in COMP}: sum{i in FEED: i ne j} x[j,i]=1;
con subtour_elimination {i in FEED, j in COMP : i ne 0 & j ne 0 & i ne j}: u[i]-u[j] + &_nCompon * x[i,j]<=&_nCompon-1;
solve with MILP;
expand;
%put &_OROPTMODEL_;
* Create optimum values of x in a SAS dataset ‘optimout1’;
create data optimout1
from [COMP FEED]
={i in COMP, j in FEED: x[i,j] ne 0}
amount=x ;
* Create optimum values of u in a SAS dataset ‘optimout2’;
create data optimout2
from [COMP]
={i in COMP: u[i]}
amount=u ;
*End of PROC OPTMODE;
quit;
%mend model;
* The report writing macro;
%macro report;
title &_title;
proc tabulate data=optimout1;
title &_title;
class COMP FEED ;
var amount;
table COMP =”COMP”,
FEED*amount*sum
/ BOX=’Component sequencing’;
run;
proc tabulate data=optimout2;
title &_title;
class COMP ;
var amount;
table COMP =”COMP”,
amount*sum
/ BOX=’Component sequencing’;
run;
%mend report;
* A SAS macro for SMT placement machines or the component sequencing problem;
%macro orcsp;
%data;
%model;
%report;
%mend orcsp;
%orcsp;
/****************************************************************************
******************************END of the program*****************************
****************************************************************************/