The following example illustrates a DATA step program for generating a linear program to solve a multicommodity network flow model that has fixed charges. Consider a network consisting of the following nodes: farm-a, farm-b, farm-c, Chicago, St. Louis, and New York. You can ship four commodities from each farm to Chicago or St. Louis and from Chicago or St. Louis to New York. The following table shows the unit shipping cost for each of the four commodities across each of the arcs. The table also shows the supply (positive numbers) at each of the from nodes and the demand (negative numbers) at each of the to nodes. The fixed charge is a fixed cost for shipping any nonzero amount across an arc. For example, if any amount of any of the four commodities is sent from farm-c to St. Louis, then a fixed charge of 75 units is added to the shipping cost.
Unit Shipping Supply and Demand Fixed From To Cost Charge Node Node 1 2 3 4 1 2 3 4 farm-a Chicago 20 15 17 22 100 100 40 . 100 farm-b Chicago 15 15 15 30 100 200 50 50 75 farm-c Chicago 30 30 10 10 40 100 75 100 100 farm-a StLouis 30 25 27 22 . . . . 150 farm-c StLouis 10 9 11 10 . . . . 75 Chicago NY 75 75 75 75 -150 -200 -50 -75 200 StLouis NY 80 80 80 80 . . . . 200
The following program is designed to take the data in the form given in the preceding table. It builds the node arc incidence
matrix for a network given in this form and adds integer variables to capture the fixed charge using the type of constraints
discussed in Example 6.8. The program solves the model using PROC LP, saves the solution in the PRIMALOUT= data set named SOLUTION
, and displays the solution. The DATA step can be easily modified to handle larger problems with similar structure.
title 'Multi-commodity Transshipment Problem with Fixed-Charges'; %macro dooversd; _coef_=sd{_i_}; if sd{_i_}>0 then do; /* the node is a supply node */ _row_=from||' commodity'||put(_i_,2.); if from^=' ' then output; end; else if sd{_i_}<0 then do; /* the node is a demand node */ _row_=to||' commodity'||put(_i_,2.); if to^=' ' then output; end; else if from^=' ' & to^=' ' then do; /* a transshipment node */ _coef_=0; _row_=from||' commodity'||put(_i_,2.); output; _row_=to ||' commodity'||put(_i_,2.); output; end; %mend dooversd; %macro dooverc; _col_=arc||' commodity'||put(_i_,2.); if from^=' ' & to^=' ' then do; /* add node arc incidence matrix */ _type_='le'; _row_=from||' commodity'||put(_i_,2.); _coef_=1; output; _row_=to ||' commodity'||put(_i_,2.); _coef_=-1; output; _type_=' '; _row_='obj'; _coef_=c{_i_}; output; /* add fixed charge variables */ _type_='le'; _row_=arc; _coef_=1; output; _col_='_rhs_'; _type_=' '; _coef_=0; output; _col_=arc||'fx'; _coef_=-M; output; _row_='int'; _coef_=1; output; _row_='obj'; _coef_=fx; output; _row_='upper'; _coef_=1; output; end; %mend dooverc;
data network; retain M 1.0e6; length _col_ $ 22 _row_ $ 22; keep _type_ _col_ _row_ _coef_ ; array sd sd1-sd4; array c c1-c4; input arc $10. from $ to $ c1 c2 c3 c4 sd1 sd2 sd3 sd4 fx; /* for the first observation define some of the rows */ if _n_=1 then do; _type_='upperbd'; _row_='upper'; output; _type_='lowerbd'; _row_='lower'; output; _type_='min'; _row_='obj'; output; _type_='integer'; _row_='int'; output; end; _col_='_rhs_'; _type_='le'; do _i_ = 1 to dim(sd); %dooversd; end; do _i_ = 1 to dim(c); %dooverc; end; datalines; a-Chicago farm-a Chicago 20 15 17 22 100 100 40 . 100 b-Chicago farm-b Chicago 15 15 15 30 100 200 50 50 75 c-Chicago farm-c Chicago 30 30 10 10 40 100 75 100 100 a-StLouis farm-a StLouis 30 25 27 22 . . . . 150 c-StLouis farm-c StLouis 10 9 11 10 . . . . 75 Chicago-NY Chicago NY 75 75 75 75 -150 -200 -50 -75 200 StLous-NY StLouis NY 80 80 80 80 . . . . 200 ; /* solve the model */ proc lp sparsedata pout=solution noprint; run;
/* print the solution */ data; set solution; rename _var_=arc _value_=amount; if _value_^=0 & _type_='NON-NEG'; run; proc print; id arc; var amount; run;
The results from this example are shown in Output 6.14.1. The NOPRINT option in the PROC LP statement suppresses the Variable and Constraint Summary sections. This is useful when solving large
models for which a report program is available. Here, the solution is saved in data set SOLUTION
and reported using PROC PRINT. The solution shows the amount that is shipped over each arc.
Output 6.14.1: Multicommodity Transshipment Problem with Fixed Charges
Multi-commodity Transshipment Problem with Fixed-Charges |
arc | amount |
---|---|
a-Chicago commodity 1 | 10 |
b-Chicago commodity 1 | 100 |
b-Chicago commodity 2 | 100 |
c-Chicago commodity 3 | 50 |
c-Chicago commodity 4 | 75 |
c-StLouis commodity 1 | 40 |
c-StLouis commodity 2 | 100 |
Chicago-NY commodity 1 | 110 |
Chicago-NY commodity 2 | 100 |
Chicago-NY commodity 3 | 50 |
Chicago-NY commodity 4 | 75 |
StLous-NY commodity 1 | 40 |
StLous-NY commodity 2 | 100 |