The following PROC OPTMODEL statements declare index sets and parameters and then read data sets to populate them:
proc optmodel; set BLOCKS; num level {BLOCKS}; num row {BLOCKS}; num column {BLOCKS}; num revenue {BLOCKS}; read data block_data into BLOCKS=[_N_] level row column revenue=percent; for {block in BLOCKS} revenue[block] = &full_value * revenue[block] / 100; set LEVELS; num cost {LEVELS}; read data level_data into LEVELS=[_N_] cost;
The following statements declare binary decision variables and the objective:
var Extract {BLOCKS} binary; num profit {block in BLOCKS} = revenue[block] - cost[level[block]]; max TotalProfit = sum {block in BLOCKS} profit[block] * Extract[block];
The following CON statement uses the colon operator (:) to enforce the rule that if you extract block i, then you must also extract each block j that lies above it:
con Precedence_con {i in BLOCKS, j in BLOCKS: level[j] = level[i] - 1 and row[j] in {row[i],row[i]+1} and column[j] in {column[i],column[i]+1} }: Extract[i] <= Extract[j];
The following SOLVE statement calls the MILP solver. However, since the constraint matrix is totally unimodular, the optimal solution of the LP relaxation is automatically integral, and hence no branching is required.
solve; print Extract profit;
The following CREATE DATA statement uses the colon operator (:) to output only the blocks that are used in the optimal solution:
create data sol_data from [block]={block in BLOCKS: Extract[block].sol > 0.5} level row column revenue cost[level[block]] profit; quit;
Figure 14.2 shows the output from the mixed integer linear programming solver.
Figure 14.2: Output from Mixed Integer Linear Programming Solver
Problem Summary | |
---|---|
Objective Sense | Maximization |
Objective Function | TotalProfit |
Objective Type | Linear |
Number of Variables | 30 |
Bounded Above | 0 |
Bounded Below | 0 |
Bounded Below and Above | 30 |
Free | 0 |
Fixed | 0 |
Binary | 30 |
Integer | 0 |
Number of Constraints | 56 |
Linear LE (<=) | 56 |
Linear EQ (=) | 0 |
Linear GE (>=) | 0 |
Linear Range | 0 |
Constraint Coefficients | 112 |
Solution Summary | |
---|---|
Solver | MILP |
Algorithm | Branch and Cut |
Objective Function | TotalProfit |
Solution Status | Optimal |
Objective Value | 17500 |
Relative Gap | 0 |
Absolute Gap | 0 |
Primal Infeasibility | 0 |
Bound Infeasibility | 0 |
Integer Infeasibility | 0 |
Best Bound | 17500 |
Nodes | 0 |
Iterations | 0 |
Presolve Time | 0.01 |
Solution Time | 0.01 |
[1] | Extract | profit |
---|---|---|
1 | 1 | 0 |
2 | 1 | 0 |
3 | 1 | 0 |
4 | 0 | -1500 |
5 | 1 | 0 |
6 | 1 | 1000 |
7 | 1 | 0 |
8 | 0 | -1500 |
9 | 1 | -1000 |
10 | 1 | -1000 |
11 | 1 | -1500 |
12 | 0 | -2000 |
13 | 0 | -1500 |
14 | 0 | -1500 |
15 | 0 | -2000 |
16 | 0 | -2500 |
17 | 1 | 2000 |
18 | 1 | 2000 |
19 | 0 | -2000 |
20 | 1 | 0 |
21 | 1 | 0 |
22 | 0 | -4000 |
23 | 0 | -2000 |
24 | 0 | -2000 |
25 | 0 | -5000 |
26 | 1 | 16000 |
27 | 0 | 4000 |
28 | 0 | 2000 |
29 | 0 | 0 |
30 | 0 | 2000 |