The OPTLP Procedure
Example 5.8 Using the Network Simplex Algorithm
This example demonstrates how to use the network simplex algorithm to find the minimum-cost flow in a directed graph. Consider the directed graph in Figure 5, which appears in Ahuja, Magnanti, and Orlin (1993).
Figure 5: Minimum-Cost Network Flow Problem: Data

You can use the following SAS statements to create the input data table ex8:
data mylib.ex8;
input _id_ field1 $8. field2 $13. @28 field3 $13. field4 @56 field5 $13. field6;
datalines;
1 NAME . . . . .
2 ROWS . . . . .
3 N obj . . . .
4 E balance['1'] . . . .
5 E balance['2'] . . . .
6 E balance['3'] . . . .
7 E balance['4'] . . . .
8 E balance['5'] . . . .
9 E balance['6'] . . . .
10 E balance['7'] . . . .
11 E balance['8'] . . . .
12 COLUMNS . . . . .
13 . x['1','4'] obj 2 balance['1'] 1
14 . x['1','4'] balance['4'] -1 . .
15 . x['2','1'] obj 1 balance['1'] -1
16 . x['2','1'] balance['2'] 1 . .
17 . x['2','3'] balance['2'] 1 balance['3'] -1
18 . x['2','6'] obj 6 balance['2'] 1
19 . x['2','6'] balance['6'] -1 . .
20 . x['3','4'] obj 1 balance['3'] 1
21 . x['3','4'] balance['4'] -1 . .
22 . x['3','5'] obj 4 balance['3'] 1
23 . x['3','5'] balance['5'] -1 . .
24 . x['4','7'] obj 5 balance['4'] 1
25 . x['4','7'] balance['7'] -1 . .
26 . x['5','6'] obj 2 balance['5'] 1
27 . x['5','6'] balance['6'] -1 . .
28 . x['5','7'] obj 7 balance['5'] 1
29 . x['5','7'] balance['7'] -1 . .
30 . x['6','8'] obj 8 balance['6'] 1
31 . x['6','8'] balance['8'] -1 . .
32 . x['7','8'] obj 9 balance['7'] 1
33 . x['7','8'] balance['8'] -1 . .
34 RHS . . . . .
35 . .RHS. balance['1'] 10 . .
36 . .RHS. balance['2'] 20 . .
37 . .RHS. balance['4'] -5 . .
38 . .RHS. balance['7'] -15 . .
39 . .RHS. balance['8'] -10 . .
40 BOUNDS . . . . .
41 UP .BOUNDS. x['1','4'] 15 . .
42 UP .BOUNDS. x['2','1'] 10 . .
43 UP .BOUNDS. x['2','3'] 10 . .
44 UP .BOUNDS. x['2','6'] 10 . .
45 UP .BOUNDS. x['3','4'] 5 . .
46 UP .BOUNDS. x['3','5'] 10 . .
47 UP .BOUNDS. x['4','7'] 10 . .
48 UP .BOUNDS. x['5','6'] 20 . .
49 UP .BOUNDS. x['5','7'] 15 . .
50 UP .BOUNDS. x['6','8'] 10 . .
51 UP .BOUNDS. x['7','8'] 15 . .
52 ENDATA . . . . .
;
You can use the following call to PROC OPTLP to find the minimum-cost flow:
proc optlp
presolver = none
printlevel = 2
logfreq = 1
data = mylib.ex8
primalout = mylib.ex8out
algorithm = ns;
run;
The optimal solution is displayed in Output 5.8.1.
Output 5.8.1: Network Simplex Algorithm: Primal Solution Output
| Primal Solution |
| Obs | Objective Function ID | RHS ID | Variable Name | Variable Type | Objective Coefficient | Lower Bound | Upper Bound | Variable Value | Variable Status | Reduced Cost |
|---|---|---|---|---|---|---|---|---|---|---|
| 1 | obj | .RHS. | x['1','4'] | D | 2 | 0 | 15 | 10 | B | 0 |
| 2 | obj | .RHS. | x['2','1'] | D | 1 | 0 | 10 | 0 | L | 1 |
| 3 | obj | .RHS. | x['2','3'] | D | 0 | 0 | 10 | 10 | B | 0 |
| 4 | obj | .RHS. | x['2','6'] | D | 6 | 0 | 10 | 10 | B | 0 |
| 5 | obj | .RHS. | x['3','4'] | D | 1 | 0 | 5 | 5 | U | -1 |
| 6 | obj | .RHS. | x['3','5'] | D | 4 | 0 | 10 | 5 | B | 0 |
| 7 | obj | .RHS. | x['4','7'] | D | 5 | 0 | 10 | 10 | U | -4 |
| 8 | obj | .RHS. | x['5','6'] | D | 2 | 0 | 20 | 0 | L | 0 |
| 9 | obj | .RHS. | x['5','7'] | D | 7 | 0 | 15 | 5 | B | 0 |
| 10 | obj | .RHS. | x['6','8'] | D | 8 | 0 | 10 | 10 | B | 0 |
| 11 | obj | .RHS. | x['7','8'] | D | 9 | 0 | 15 | 0 | L | 6 |
The optimal solution is represented graphically in Figure 6.
Figure 6: Minimum-Cost Network Flow Problem: Optimal Solution

The iteration log is displayed in Output 5.8.2.
Output 5.8.2: Log: Solution Progress
| NOTE: The problem has 11 variables (0 free, 0 fixed). |
| NOTE: The problem has 8 constraints (0 LE, 8 EQ, 0 GE, 0 range). |
| NOTE: The problem has 22 constraint coefficients. |
| NOTE: The LP presolver value NONE is applied. |
| NOTE: The LP solver is called. |
| NOTE: The Network Simplex algorithm is used. |
| NOTE: The network has 8 rows (100.00%), 11 columns (100.00%), and 1 component. |
| NOTE: The network extraction and setup time is 0.00 seconds. |
| Primal Primal Dual |
| Iteration Objective Infeasibility Infeasibility Time |
| 1 0.000000E+00 2.000000E+01 8.900000E+01 0.00 |
| 2 0.000000E+00 2.000000E+01 8.900000E+01 0.00 |
| 3 5.000000E+00 1.500000E+01 2.666667E+01 0.00 |
| 4 5.000000E+00 1.500000E+01 2.766667E+01 0.00 |
| 5 7.500000E+01 1.500000E+01 2.666667E+01 0.00 |
| 6 7.500000E+01 1.500000E+01 1.580000E+01 0.00 |
| 7 1.300000E+02 1.000000E+01 2.533333E+01 0.00 |
| 8 2.700000E+02 0.000000E+00 0.000000E+00 0.00 |
| NOTE: The Network Simplex solve time is 0.00 seconds. |
| NOTE: The total Network Simplex solve time is 0.00 seconds. |
| NOTE: Optimal. |
| NOTE: Objective = 270. |
| NOTE: The Cloud Analytic Services server processed the request in 0.289664 |
| seconds. |
| NOTE: The data set MYLIB.EX8OUT has 11 observations and 10 variables. |