The Decomposition Algorithm

Example 16.6 Resource Allocation Problem

(View the complete code for this example.)

This example describes a model for selecting tasks to be run on a shared resource (Gamrath 2010). Consider a set I of tasks and a resource capacity C. Each item i element of upper I has a profit p Subscript i, a resource utilization level w Subscript i, a starting period s Subscript i, and an ending period e Subscript i. The time horizon that is considered is from the earliest starting time to the latest ending time of all tasks. With each task, associate a binary variable x Subscript i, which, if set to 1, indicates that the task is running from its start time until just before its end time. A task consumes capacity if it is running. The goal is to select which tasks to run in order to maximize profit while not exceeding the shared resource capacity. Let upper S equals StartSet s Subscript i Baseline vertical bar i element of upper I EndSet define the set of start times for all tasks, and let upper L Subscript s Baseline equals StartSet i element of upper I vertical bar s Subscript i Baseline less than or equals s less than e Subscript i Baseline EndSet define the set of tasks that are running at each start time s element of upper S. You can model the problem as a mixed integer linear programming problem as follows:

StartLayout 1st Row 1st Column Blank 2nd Column maximize 3rd Column sigma summation Underscript i element of upper I Endscripts p Subscript i Baseline x Subscript i 2nd Row 1st Column Blank 2nd Column subject to 3rd Column sigma summation Underscript i element of upper L Subscript s Endscripts w Subscript i Baseline x Subscript i 4th Column less than or equals upper C 5th Column Blank 6th Column s element of upper S 7th Column Blank 8th Column left parenthesis CapacityCon right parenthesis 3rd Row 1st Column Blank 2nd Column Blank 3rd Column x Subscript i 4th Column element of StartSet 0 comma 1 EndSet 5th Column Blank 6th Column i element of upper I EndLayout

In this formulation, the CapacityCon constraints ensure that the running tasks do not exceed the resource capacity. To illustrate, consider the following five-task example with data: p Subscript i Baseline equals left parenthesis 6 comma 8 comma 5 comma 9 comma 8 right parenthesis, w Subscript i Baseline equals left parenthesis 8 comma 5 comma 3 comma 4 comma 3 right parenthesis, s Subscript i Baseline equals left parenthesis 1 comma 3 comma 5 comma 7 comma 8 right parenthesis, e Subscript i Baseline equals left parenthesis 5 comma 8 comma 9 comma 17 comma 10 right parenthesis, and upper C equals 10. The formulation leads to a constraint matrix that has a staircase structure that is determined by tasks coming online and offline:

StartLayout 1st Row 1st Column maximize 2nd Column 6 x 1 3rd Column plus 4th Column 8 x 2 5th Column plus 6th Column 5 x 3 7th Column plus 8th Column 9 x 4 9th Column plus 10th Column 8 x 5 2nd Row 1st Column subject to 2nd Column 8 x 1 3rd Column Blank 4th Column Blank 5th Column Blank 6th Column Blank 7th Column Blank 8th Column Blank 9th Column Blank 10th Column Blank 11th Column less than or equals 12th Column 10 3rd Row 1st Column Blank 2nd Column 8 x 1 3rd Column plus 4th Column 5 x 2 5th Column Blank 6th Column Blank 7th Column Blank 8th Column Blank 9th Column Blank 10th Column Blank 11th Column less than or equals 12th Column 10 4th Row 1st Column Blank 2nd Column Blank 3rd Column Blank 4th Column 5 x 2 5th Column plus 6th Column 3 x 3 7th Column Blank 8th Column Blank 9th Column Blank 10th Column Blank 11th Column less than or equals 12th Column 10 5th Row 1st Column Blank 2nd Column Blank 3rd Column Blank 4th Column 5 x 2 5th Column plus 6th Column 3 x 3 7th Column plus 8th Column 4 x 4 9th Column Blank 10th Column Blank 11th Column less than or equals 12th Column 10 6th Row 1st Column Blank 2nd Column Blank 3rd Column Blank 4th Column Blank 5th Column Blank 6th Column 3 x 3 7th Column plus 8th Column 4 x 4 9th Column plus 10th Column 3 x 5 11th Column less than or equals 12th Column 10 7th Row 1st Column Blank 2nd Column Blank 3rd Column Blank 4th Column Blank 5th Column Blank 6th Column Blank 7th Column Blank 8th Column Blank 9th Column Blank 10th Column x Subscript i 11th Column element of 12th Column StartSet 0 comma 1 EndSet i element of upper I EndLayout

Lagrangian Decomposition

This formulation clearly has no decomposable structure. However, you can use a common modeling technique known as Lagrangian decomposition to bring the model into block-angular form. Lagrangian decomposition works by first partitioning the constraints into blocks. Then, each original variable is split into multiple copies of itself, one copy for each block in which the variable has a nonzero coefficient in the constraint matrix. Constraints are added to enforce the equality of each copy of the original variable. Then, you can write the original constraints in block-angular form by using the duplicate variables.

To apply Lagrangian decomposition to the resource allocation problem, define a set B of blocks and let upper S Subscript b define the set of start times for a given block b, such that upper S equals union Subscript b element of upper B Baseline upper S Subscript b. Given this partition of start times, let upper B Subscript i define the set of blocks in which task i element of upper I is scheduled to be running. Now, for each task i element of upper I, define duplicate variables x Subscript i Superscript b for each b element of upper B Subscript i. Let m Subscript i define the minimum block index for each class of variable that represents task i. You can now model the problem in block-angular form as follows:

StartLayout 1st Row 1st Column Blank 2nd Column maximize 3rd Column sigma summation Underscript i element of upper I Endscripts p Subscript i Baseline x Subscript i Superscript m Super Subscript i 2nd Row 1st Column Blank 2nd Column subject to 3rd Column x Subscript i Superscript b 4th Column equals x Subscript i Superscript m Super Subscript i Baseline 5th Column Blank 6th Column i element of upper I comma b element of upper B Subscript i Baseline minus StartSet m Subscript i Baseline EndSet 7th Column Blank 8th Column left parenthesis LinkDupVarsCon right parenthesis 3rd Row 1st Column Blank 2nd Column Blank 3rd Column sigma summation Underscript i element of upper L Subscript s Endscripts w Subscript i Baseline x Subscript i Superscript b 4th Column less than or equals upper C 5th Column Blank 6th Column b element of upper B comma s element of upper S Subscript b Baseline 7th Column Blank 8th Column left parenthesis CapacityCon right parenthesis 4th Row 1st Column Blank 2nd Column Blank 3rd Column x Subscript i Superscript b 4th Column element of StartSet 0 comma 1 EndSet 5th Column Blank 6th Column i element of upper I comma b element of upper B Subscript i Baseline EndLayout

In this formulation, the LinkDupVarsCon constraints ensure that the duplicate variables are equal to the original variables. Now, the five-task example has been transformed from a staircase structure to a block-angular structure:

StartLayout 1st Row 1st Column maximize 2nd Column 6 x 1 Superscript 1 3rd Column plus 4th Column 8 x 2 Superscript 1 5th Column Blank 6th Column Blank 7th Column plus 8th Column 5 x 3 squared 9th Column plus 10th Column 9 x 4 squared 11th Column Blank 12th Column Blank 13th Column Blank 14th Column Blank 15th Column plus 16th Column 8 x 5 cubed 2nd Row 1st Column subject to 2nd Column Blank 3rd Column Blank 4th Column x 2 Superscript 1 5th Column minus 6th Column x 2 squared 7th Column Blank 8th Column Blank 9th Column Blank 10th Column Blank 11th Column Blank 12th Column Blank 13th Column Blank 14th Column Blank 15th Column Blank 16th Column Blank 17th Column equals 0 3rd Row 1st Column Blank 2nd Column Blank 3rd Column Blank 4th Column Blank 5th Column Blank 6th Column Blank 7th Column Blank 8th Column x 3 squared 9th Column Blank 10th Column Blank 11th Column minus 12th Column x 3 cubed 13th Column Blank 14th Column Blank 15th Column Blank 16th Column Blank 17th Column equals 0 4th Row 1st Column Blank 2nd Column Blank 3rd Column Blank 4th Column Blank 5th Column Blank 6th Column Blank 7th Column Blank 8th Column Blank 9th Column Blank 10th Column x 4 squared 11th Column Blank 12th Column Blank 13th Column minus 14th Column x 4 cubed 15th Column Blank 16th Column Blank 17th Column equals 0 5th Row 1st Column Blank 2nd Column 8 x 1 Superscript 1 3rd Column Blank 4th Column Blank 5th Column Blank 6th Column Blank 7th Column Blank 8th Column Blank 9th Column Blank 10th Column Blank 11th Column Blank 12th Column Blank 13th Column Blank 14th Column Blank 15th Column Blank 16th Column Blank 17th Column less than or equals 10 6th Row 1st Column Blank 2nd Column 8 x 1 Superscript 1 3rd Column plus 4th Column 5 x 2 Superscript 1 5th Column Blank 6th Column Blank 7th Column Blank 8th Column Blank 9th Column Blank 10th Column Blank 11th Column Blank 12th Column Blank 13th Column Blank 14th Column Blank 15th Column Blank 16th Column Blank 17th Column less than or equals 10 7th Row 1st Column Blank 2nd Column Blank 3rd Column Blank 4th Column Blank 5th Column Blank 6th Column 5 x 2 squared 7th Column plus 8th Column 3 x 3 squared 9th Column Blank 10th Column Blank 11th Column Blank 12th Column Blank 13th Column Blank 14th Column Blank 15th Column Blank 16th Column Blank 17th Column less than or equals 10 8th Row 1st Column Blank 2nd Column Blank 3rd Column Blank 4th Column Blank 5th Column Blank 6th Column 5 x 2 squared 7th Column plus 8th Column 3 x 3 squared 9th Column plus 10th Column 4 x 4 squared 11th Column Blank 12th Column Blank 13th Column Blank 14th Column Blank 15th Column Blank 16th Column Blank 17th Column less than or equals 10 9th Row 1st Column Blank 2nd Column Blank 3rd Column Blank 4th Column Blank 5th Column Blank 6th Column Blank 7th Column Blank 8th Column Blank 9th Column Blank 10th Column Blank 11th Column Blank 12th Column 3 x 3 cubed 13th Column plus 14th Column 4 x 4 cubed 15th Column plus 16th Column 3 x 5 cubed 17th Column less than or equals 10 10th Row 1st Column Blank 2nd Column Blank 3rd Column Blank 4th Column Blank 5th Column Blank 6th Column Blank 7th Column Blank 8th Column Blank 9th Column Blank 10th Column Blank 11th Column Blank 12th Column Blank 13th Column Blank 14th Column Blank 15th Column Blank 16th Column x Subscript i Superscript b 17th Column element of StartSet 0 comma 1 EndSet i element of upper I comma b element of upper B Subscript i Baseline EndLayout

To see how to apply Lagrangian decomposition in PROC OPTMODEL, consider the data set TaskData from Caprara, Furini, and Malaguti (2010), which consists of StartAbsoluteValue upper I EndAbsoluteValue equals 2,916 tasks:

data TaskData;
   input profit weight start end;
   datalines;
99 92 1 9
56 30 1 3
39 73 1 20
86 76 1 9
...
24 94 768 769
95 40 768 769
66 17 768 769
18 48 768 769
97 23 768 769
;

Using the MILP Solver Directly in PROC OPTMODEL

The following PROC OPTMODEL statements read in the data and solve the original staircase formulation by calling the MILP solver directly:

%macro SetupData(task_data=, capacity=);
   set TASKS;
   num capacity=&capacity;
   num profit{TASKS}, weight{TASKS}, start{TASKS}, end{TASKS};

   read data &task_data into TASKS=[_n_] profit weight start end;
   /* the set of start times */

   set STARTS = setof{i in TASKS} start[i];
   /* the set of tasks i that are active at a given start time s */
   set TASKS_START{s in STARTS}
      = {i in TASKS: start[i] <= s < end[i]};
%mend SetupData;

%macro ResourceAllocation_Direct(task_data=, capacity=);
   proc optmodel;
      %SetupData(task_data=&task_data,capacity=&capacity);

      /* select task i to come online from period [start to end) */
      var x{TASKS} binary;

      /* maximize the total profit of running tasks */
      max TotalProfit = sum{i in TASKS} profit[i] * x[i];

      /* enforce that the shared resource capacity is not exceeded */
      con CapacityCon{s in STARTS}:
         sum{i in TASKS_START[s]} weight[i] * x[i] <= capacity;

      solve with milp / maxtime=200 logfreq=10000;
   quit;
%mend ResourceAllocation_Direct;

%ResourceAllocation_Direct(task_data=TaskData, capacity=100);

The problem summary and solution summary are displayed in Output 16.6.1.

Output 16.6.1: Problem Summary and Solution Summary

The OPTMODEL Procedure

Problem Summary
Objective SenseMaximization
Objective FunctionTotalProfit
Objective TypeLinear
  
Number of Variables2916
Bounded Above0
Bounded Below0
Bounded Below and Above2916
Free0
Fixed0
Binary2916
Integer0
  
Number of Constraints768
Linear LE (<=)768
Linear EQ (=)0
Linear GE (>=)0
Linear Range0
  
Constraint Coefficients23236

Solution Summary
SolverMILP
AlgorithmBranch and Cut
Objective FunctionTotalProfit
Solution StatusOptimal within Relative Gap
Objective Value40982
  
Relative Gap0.0000980648
Absolute Gap4.0192857192
Primal Infeasibility0
Bound Infeasibility0
Integer Infeasibility0
  
Best Bound40986.019286
Nodes5084
Solutions Found19
Iterations214002
Presolve Time0.10
Solution Time18.59


The iteration log, which contains the problem statistics, the progress of the solution, and the best integer feasible solution found, is shown in Output 16.6.2.

Output 16.6.2: Log

NOTE: There were 2916 observations read from the data set WORK.TASKDATA.                        
NOTE: Problem generation will use 4 threads.                                                    
NOTE: The problem has 2916 variables (0 free, 0 fixed).                                         
NOTE: The problem has 2916 binary and 0 integer variables.                                      
NOTE: The problem has 768 linear constraints (768 LE, 0 EQ, 0 GE, 0 range).                     
NOTE: The problem has 23236 linear constraint coefficients.                                     
NOTE: The problem has 0 nonlinear constraints (0 LE, 0 EQ, 0 GE, 0 range).                      
NOTE: The remaining solution time after problem generation and solver initialization is 199.52  
      seconds.                                                                                  
NOTE: The initial MILP heuristics are applied.                                                  
NOTE: The MILP presolver value AUTOMATIC is applied.                                            
NOTE: The MILP presolver removed 1021 variables and 126 constraints.                            
NOTE: The MILP presolver removed 12544 constraint coefficients.                                 
NOTE: The MILP presolver modified 987 constraint coefficients.                                  
NOTE: The presolved problem has 1895 variables, 642 constraints, and 10692 constraint           
      coefficients.                                                                             
NOTE: The MILP solver is called.                                                                
NOTE: The parallel Branch and Cut algorithm is used.                                            
NOTE: The Branch and Cut algorithm is using up to 4 threads.                                    
          Node   Active   Sols    BestInteger      BestBound      Gap    Time                   
             0        1      3  33939.0000000         109181   68.91%       0                   
             0        1      3  33939.0000000  45862.9249030   26.00%       0                   
             0        1      7  39381.0000000  45862.9249030   14.13%       0                   
             0        1      7  39381.0000000  43471.6068311    9.41%       0                   
             0        1      7  39381.0000000  42707.3723942    7.79%       0                   
             0        1      7  39381.0000000  42238.8588892    6.77%       0                   
             0        1      7  39381.0000000  41967.3454237    6.16%       1                   
             0        1      7  39381.0000000  41743.7098575    5.66%       1                   
             0        1      7  39381.0000000  41616.2315360    5.37%       1                   
             0        1      7  39381.0000000  41502.8003604    5.11%       1                   
             0        1      7  39381.0000000  41413.3091253    4.91%       2                   
             0        1      7  39381.0000000  41356.7303013    4.78%       2                   
             0        1     10  40606.0000000  41356.7303013    1.82%       2                   
             0        1     10  40606.0000000  41319.7929965    1.73%       2                   
             0        1     10  40606.0000000  41291.0535691    1.66%       2                   
             0        1     10  40606.0000000  41257.4586910    1.58%       3                   
             0        1     10  40606.0000000  41230.7941340    1.52%       3                   
             0        1     10  40606.0000000  41211.5099745    1.47%       3                   
             0        1     10  40606.0000000  41195.4072860    1.43%       3                   
             0        1     10  40606.0000000  41178.0811024    1.39%       3                   
             0        1     10  40606.0000000  41168.0422830    1.37%       4                   
             0        1     10  40606.0000000  41157.1566155    1.34%       4                   
             0        1     10  40606.0000000  41148.9202354    1.32%       4                   
             0        1     10  40606.0000000  41144.7920422    1.31%       4                   
NOTE: The MILP solver added 817 cuts with 10610 cut coefficients at the root.                   
           316        4     11  40879.0000000  41113.8580323    0.57%       6                   
          1408      862     12  40930.0000000  41071.5367400    0.34%       8                   
          2156     1276     13  40943.0000000  41053.2643070    0.27%      10                   
          2726     1442     14  40972.0000000  41043.6598465    0.17%      12                   
          2780     1456     15  40976.0000000  41043.5767327    0.16%      12                   
          3783     1039     16  40978.0000000  41011.8999490    0.08%      15                   
          3870      998     17  40979.0000000  41006.9850849    0.07%      16                   
          5022      286     18  40981.0000000  40987.3881588    0.02%      18                   
          5083      195     19  40982.0000000  40986.0192857    0.01%      18                   
NOTE: Optimal within relative gap.                                                              
NOTE: Objective = 40982.                                                                        


Using the Decomposition Algorithm in PROC OPTMODEL

To transform this data into block-angular form, first sort the task data to help reduce the number of duplicate variables that are needed in the reformulation as follows:

proc sort data=TaskData;
   by start end;
run;

Then, create the partition of constraints into blocks of size block_size as follows:

%macro ResourceAllocation_Decomp(task_data=, capacity=, block_size=);
   proc optmodel;
      %SetupData(task_data=&task_data,capacity=&capacity);
      /* partition into blocks of size blocks_size */
      num block_size = &block_size;
      num num_blocks = ceil( card(TASKS) / block_size );
      set BLOCKS     = 1..num_blocks;

      /* the set of starts s for which task i is active */
      set STARTS_TASK{i in TASKS} = {s in STARTS: start[i] <= s < end[i]};

      /* partition the start times into blocks of size block_size */
      set STARTS_BLOCK{BLOCKS} init {};
      num block_id    init 1;
      num block_count init 0;
      for{s in STARTS} do;
         STARTS_BLOCK[block_id] = STARTS_BLOCK[block_id] union {s};
         block_count = block_count + 1;
         if(mod(block_count, block_size) = 0) then
             block_id = block_id + 1;
      end;

Then, use the following PROC OPTMODEL statements to define the block-angular formulation and solve the problem by using the decomposition algorithm, the PRESOLVER=BASIC option, and block_size=20. Because this reformulation is equivalent to the original staircase formulation, disabling some of the advanced presolver techniques ensures that the model maintains block-angularity.

      /* blocks in which task i is online */
      set BLOCKS_TASK{i in TASKS} =
         {b in BLOCKS: card(STARTS_BLOCK[b] inter STARTS_TASK[i]) > 0};

      /* minimum block id in which task i is online */
      num min_block{i in TASKS} = min{b in BLOCKS_TASK[i]} b;

      /* select task i to come online from period [start to end)
         in each block */
      var x{i in TASKS, b in BLOCKS_TASK[i]} binary;

      /* maximize the total profit of running tasks */
      max TotalProfit = sum{i in TASKS} profit[i] * x[i,min_block[i]];

      /* enforce that task selection is consistent across blocks */
      con LinkDupVarsCon{i in TASKS, b in BLOCKS_TASK[i] diff {min_block[i]}}:
         x[i,b] = x[i,min_block[i]];

      /* enforce that the shared resource capacity is not exceeded */
      con CapacityCon{b in BLOCKS, s in STARTS_BLOCK[b]}:
         sum{i in TASKS_START[s]} weight[i] * x[i,b] <= capacity;

      /* define blocks for decomposition algorithm */
      for{b in BLOCKS, s in STARTS_BLOCK[b]} CapacityCon[b,s].block = b;

      solve with milp / presolver=basic decomp;
   quit;
%mend ResourceAllocation_Decomp;

%ResourceAllocation_Decomp(task_data=TaskData, capacity=100, block_size=20);

The problem summary and solution summary are displayed in Output 16.6.3. Compared to the original formulation, the numbers of variables and constraints are increased by the number of duplicate variables.

Output 16.6.3: Problem Summary and Solution Summary

The OPTMODEL Procedure

Problem Summary
Objective SenseMaximization
Objective FunctionTotalProfit
Objective TypeLinear
  
Number of Variables3924
Bounded Above0
Bounded Below0
Bounded Below and Above3924
Free0
Fixed0
Binary3924
Integer0
  
Number of Constraints1776
Linear LE (<=)768
Linear EQ (=)1008
Linear GE (>=)0
Linear Range0
  
Constraint Coefficients25252

Solution Summary
SolverMILP
AlgorithmDecomposition
Objective FunctionTotalProfit
Solution StatusOptimal within Relative Gap
Objective Value40982
  
Relative Gap0.0000731975
Absolute Gap3
Primal Infeasibility2.88658E-15
Bound Infeasibility2.88658E-15
Integer Infeasibility2.88658E-15
  
Best Bound40985
Nodes15
Solutions Found72
Iterations258
Presolve Time0.06
Solution Time92.54


The iteration log, which contains the problem statistics, the progress of the solution, and the optimal objective value, is shown in Output 16.6.4.

Output 16.6.4: Log

NOTE: There were 2916 observations read from the data set WORK.TASKDATA.                        
NOTE: Problem generation will use 4 threads.                                                    
NOTE: The problem has 3924 variables (0 free, 0 fixed).                                         
NOTE: The problem has 3924 binary and 0 integer variables.                                      
NOTE: The problem has 1776 linear constraints (768 LE, 1008 EQ, 0 GE, 0 range).                 
NOTE: The problem has 25252 linear constraint coefficients.                                     
NOTE: The problem has 0 nonlinear constraints (0 LE, 0 EQ, 0 GE, 0 range).                      
NOTE: The initial MILP heuristics are applied.                                                  
NOTE: The MILP presolver value BASIC is applied.                                                
NOTE: The MILP presolver removed 4 variables and 0 constraints.                                 
NOTE: The MILP presolver removed 23 constraint coefficients.                                    
NOTE: The MILP presolver modified 7312 constraint coefficients.                                 
NOTE: The presolved problem has 3920 variables, 1776 constraints, and 25229 constraint          
      coefficients.                                                                             
NOTE: The MILP solver is called.                                                                
NOTE: The Decomposition algorithm is used.                                                      
NOTE: The Decomposition algorithm is executing in single-machine mode.                          
NOTE: The DECOMP method value USER is applied.                                                  
NOTE: The problem has a decomposable structure with 39 blocks. The largest block covers 1.126%  
      of the constraints in the problem.                                                        
NOTE: The decomposition subproblems cover 3920 (100%) variables and 768 (43.24%) constraints.   
NOTE: The deterministic parallel mode is enabled.                                               
NOTE: The Decomposition algorithm is using up to 4 threads.                                     
      Iter         Best       Master         Best       LP       IP  CPU Real                   
                  Bound    Objective      Integer      Gap      Gap Time Time                   
         .   44109.0000   37660.0000   37660.0000   14.62%   14.62%    1    0                   
         7   44109.0000   37916.0000   37916.0000   14.04%   14.04%    3    1                   
         9   44109.0000   38118.0000   38118.0000   13.58%   13.58%    5    2                   
         .   44109.0000   38118.0000   38118.0000   13.58%   13.58%    5    2                   
        10   44109.0000   38118.0000   38118.0000   13.58%   13.58%    6    2                   
        11   44109.0000   38236.0000   38236.0000   13.31%   13.31%    6    2                   
        14   44109.0000   38679.0000   38679.0000   12.31%   12.31%    8    3                   
        18   44109.0000   39086.0000   39077.0000   11.39%   11.41%   10    4                   
         .   44109.0000   39645.0000   39645.0000   10.12%   10.12%   10    4                   
        20   44109.0000   39645.0000   39645.0000   10.12%   10.12%   11    4                   
        22   44109.0000   39681.0000   39681.0000   10.04%   10.04%   12    5                   
        23   44109.0000   39741.5000   39740.0000    9.90%    9.91%   14    5                   
        25   44109.0000   39829.5000   39828.0000    9.70%    9.71%   15    6                   
        30   44109.0000   40334.0000   40334.0000    8.56%    8.56%   19    8                   
        35   44109.0000   40440.8333   40439.0000    8.32%    8.32%   26   10                   
         .   44109.0000   40455.9167   40448.0000    8.28%    8.30%   33   13                   
        40   44109.0000   40455.9167   40448.0000    8.28%    8.30%   35   13                   
        41   43745.1461   40455.9167   40448.0000    7.52%    7.54%   38   14                   
        42   43569.2923   40467.0000   40448.0000    7.12%    7.16%   40   15                   
        43   43157.1594   40467.0000   40448.0000    6.23%    6.28%   43   16                   
        46   43157.1594   40477.0000   40462.0000    6.21%    6.24%   46   17                   
        50   43157.1594   40519.9183   40580.0000    6.11%    5.97%   52   19                   
        51   43157.1594   40609.0000   40584.0000    5.90%    5.96%   54   20                   
        52   43157.1594   40609.0000   40594.0000    5.90%    5.94%   56   20                   
        54   43157.1594   40706.3333   40689.0000    5.68%    5.72%   57   21                   
        60   43157.1594   40791.3430   40689.0000    5.48%    5.72%   68   25                   
        61   41745.3669   40806.5044   40689.0000    2.25%    2.53%   71   26                   
        63   41622.2702   40846.9914   40689.0000    1.86%    2.24%   76   28                   
        70   41622.2702   40911.9167   40689.0000    1.71%    2.24%   86   31                   
         .   41622.2702   40991.0833   40911.0000    1.52%    1.71%   95   34                   
        80   41622.2702   40991.0833   40911.0000    1.52%    1.71%   96   34                   
        81   41071.9167   40991.0833   40911.0000    0.20%    0.39%   98   35                   
        83   41054.6944   40991.0833   40911.0000    0.15%    0.35%   99   35                   
        90   41054.6944   40997.5833   40911.0000    0.14%    0.35%  101   36                   
        98   41008.0833   40997.5833   40911.0000    0.03%    0.24%  103   38                   
        99   41005.5833   40997.5833   40911.0000    0.02%    0.23%  103   38                   
       100   41005.5833   40997.5833   40911.0000    0.02%    0.23%  103   38                   
       101   41000.5833   40997.5833   40911.0000    0.01%    0.22%  104   38                   
NOTE: The Decomposition algorithm stopped on the continuous RELOBJGAP= option.                  
         .   41000.5833   40997.5833   40936.0000    0.01%    0.16%  104   38                   
NOTE: Starting branch and bound.                                                                
         Node  Active   Sols         Best         Best      Gap    CPU   Real                   
                                  Integer        Bound            Time   Time                   
            0       1     70   40936.0000   41000.5833    0.16%    104     38                   
            1       3     70   40936.0000   41000.5833    0.16%    134     48                   
            3       5     70   40936.0000   40991.5833    0.14%    169     60                   
            5       3     71   40981.0000   40991.5833    0.03%    174     62                   
            8       4     72   40982.0000   40991.5833    0.02%    207     73                   
           11       1     72   40982.0000   40987.3333    0.01%    237     84                   
           14       0     72   40982.0000   40985.0000    0.01%    259     92                   
NOTE: The Decomposition algorithm used 4 threads.                                               
NOTE: The Decomposition algorithm time is 92.54 seconds.                                        
NOTE: Optimal within relative gap.                                                              
NOTE: Objective = 40982.                                                                        


The Trade-Off between Coverage and Subproblem Difficulty

The reformulation of this resource allocation problem provides a nice example of the potential trade-offs in modeling a problem for use with the decomposition algorithm. As seen in Example 16.2, the strength of the bound is an important factor in the overall performance of the algorithm, but it is not always correlated to the magnitude of the subproblem coverage. In the current example, the block size determines the number of blocks. Moreover, it determines the number of linking variables that are needed in the reformulation. At one extreme, if the block size is set to be StartAbsoluteValue upper S EndAbsoluteValue, then the number of blocks is 1, and the number of copies of original variables is 0. Using one block would be equivalent to the original staircase formulation and would not yield a model conducive to decomposition. As the number of blocks is increased, the number of linking variables increases (the size of the master problem), the strength of the decomposition bound decreases, and the difficulty of solving the subproblems decreases. In addition, as the number of blocks and their relative difficulty change, the efficient utilization of your machine’s parallel architecture can be affected.

The previous section used a block size of 20. The following statement calls the decomposition algorithm and uses a block size of 80:

%ResourceAllocation_Decomp(task_data=TaskData, capacity=100, block_size=80);

The solution summary is displayed in Output 16.6.5.

Output 16.6.5: Solution Summary

The OPTMODEL Procedure

Solution Summary
SolverMILP
AlgorithmDecomposition
Objective FunctionTotalProfit
Solution StatusOptimal
Objective Value40982
  
Relative Gap0
Absolute Gap0
Primal Infeasibility1.421085E-14
Bound Infeasibility1.332268E-15
Integer Infeasibility2.88658E-15
  
Best Bound40982
Nodes1
Solutions Found52
Iterations49
Presolve Time0.05
Solution Time47.90


The iteration log, which contains the problem statistics, the progress of the solution, and the optimal objective value, is shown in Output 16.6.6.

This version of the model provides a stronger initial bound and solves to optimality in the root node.

Output 16.6.6: Log

NOTE: There were 2916 observations read from the data set WORK.TASKDATA.                        
NOTE: Problem generation will use 4 threads.                                                    
NOTE: The problem has 3151 variables (0 free, 0 fixed).                                         
NOTE: The problem has 3151 binary and 0 integer variables.                                      
NOTE: The problem has 1003 linear constraints (768 LE, 235 EQ, 0 GE, 0 range).                  
NOTE: The problem has 23706 linear constraint coefficients.                                     
NOTE: The problem has 0 nonlinear constraints (0 LE, 0 EQ, 0 GE, 0 range).                      
NOTE: The initial MILP heuristics are applied.                                                  
NOTE: The MILP presolver value BASIC is applied.                                                
NOTE: The MILP presolver removed 5 variables and 0 constraints.                                 
NOTE: The MILP presolver removed 29 constraint coefficients.                                    
NOTE: The MILP presolver modified 7312 constraint coefficients.                                 
NOTE: The presolved problem has 3146 variables, 1003 constraints, and 23677 constraint          
      coefficients.                                                                             
NOTE: The MILP solver is called.                                                                
NOTE: The Decomposition algorithm is used.                                                      
NOTE: The Decomposition algorithm is executing in single-machine mode.                          
NOTE: The DECOMP method value USER is applied.                                                  
NOTE: The problem has a decomposable structure with 10 blocks. The largest block covers 7.976%  
      of the constraints in the problem.                                                        
NOTE: The decomposition subproblems cover 3146 (100%) variables and 768 (76.57%) constraints.   
NOTE: The deterministic parallel mode is enabled.                                               
NOTE: The Decomposition algorithm is using up to 4 threads.                                     
      Iter         Best       Master         Best       LP       IP  CPU Real                   
                  Bound    Objective      Integer      Gap      Gap Time Time                   
         .   41762.0080   37518.0000   37518.0000   10.16%   10.16%    3    1                   
         8   41762.0080   38555.0000   38555.0000    7.68%    7.68%   12    4                   
        10   41762.0080   38555.0000   38564.0000    7.68%    7.66%   15    5                   
        12   41762.0080   39024.0000   39024.0000    6.56%    6.56%   18    6                   
        15   41762.0080   40682.0000   40682.0000    2.59%    2.59%   25    8                   
        19   41762.0080   40787.0000   40787.0000    2.33%    2.33%   34   11                   
         .   41762.0080   40787.0000   40787.0000    2.33%    2.33%   34   12                   
        20   41762.0080   40787.0000   40787.0000    2.33%    2.33%   37   13                   
        25   41762.0080   40793.0000   40793.0000    2.32%    2.32%   54   18                   
        27   41762.0080   40824.0000   40824.0000    2.25%    2.25%   64   22                   
        28   41556.4875   40824.0000   40824.0000    1.76%    1.76%   69   24                   
        29   41322.1701   40824.0000   40824.0000    1.21%    1.21%   74   25                   
        30   41322.1701   40824.0000   40824.0000    1.21%    1.21%   77   26                   
        32   41322.1701   40883.0000   40883.0000    1.06%    1.06%   83   28                   
        33   41322.1701   40937.0000   40937.0000    0.93%    0.93%   86   29                   
        37   41322.1701   40978.0000   40978.0000    0.83%    0.83%   97   35                   
         .   41322.1701   40980.0000   40980.0000    0.83%    0.83%  102   36                   
        40   41322.1701   40980.0000   40980.0000    0.83%    0.83%  103   37                   
        41   41004.0000   40980.0000   40980.0000    0.06%    0.06%  108   39                   
        42   40992.6000   40980.0000   40980.0000    0.03%    0.03%  110   40                   
        46   40992.6000   40982.0000   40982.0000    0.03%    0.03%  118   44                   
        49   40982.0000   40982.0000   40982.0000    0.00%    0.00%  121   47                   
         Node  Active   Sols         Best         Best      Gap    CPU   Real                   
                                  Integer        Bound            Time   Time                   
            0       1     52   40982.0000   40982.0000    0.00%    121     47                   
NOTE: The Decomposition algorithm used 4 threads.                                               
NOTE: The Decomposition algorithm time is 47.90 seconds.                                        
NOTE: Optimal.                                                                                  
NOTE: Objective = 40982.                                                                        


Last updated: October 07, 2022