DUAL Command

The DUAL command displays the dual formulation of the current model.  Every linear programming model has a corresponding, mirror-image formulation called the dual.  If the original model has M constraints and N variables, then its dual will have N constraints and M variables.

Some interesting properties of the dual are that any feasible solution to the dual model provides a bound on the objective to the original, primal model, while the optimal solution to the dual has the same objective value as the optimal solution to the primal problem.  It's also true that the dual of the dual model is, once again, the original primal model.  You may wish to refer to any good linear programming text for a further discussion of duality theory.

As an example, consider the following small transportation model:

MODEL:

! A 3 Warehouse, 4 Customer

  Transportation Problem;

SETS:

  WAREHOUSE / WH1, WH2, WH3/   : CAPACITY;

  CUSTOMER   / C1, C2, C3, C4/ : DEMAND;

  ROUTES( WAREHOUSE, CUSTOMER) : COST, VOLUME;

ENDSETS

 

! The objective;

[OBJ] MIN = @SUM( ROUTES: COST * VOLUME);

 

! The demand constraints;

@FOR( CUSTOMER( J): [DEM]

 @SUM( WAREHOUSE( I): VOLUME( I, J)) >=

  DEMAND( J));

 

! The supply constraints;

@FOR( WAREHOUSE( I): [SUP]

 @SUM( CUSTOMER( J): VOLUME( I, J)) <=

  CAPACITY( I));

 

! Here are the parameters;

DATA:

  CAPACITY =   30, 25, 21 ;

  DEMAND =   15, 17, 22, 12;

  COST =      6,  2,  6,  7,

              4,  9,  5,  3,

              8,  8,  1,  5;

ENDDATA

END

Model: TRAN.LNG

If the sample session below, we load the sample model TRAN.LNG and use the DUAL command to generate its dual formulation:

: take \lingo\samples\tran.lng

: dual

 

 MODEL:

 MAX = 15 * DEM_C1 + 17 * DEM_C2 + 22 * DEM_C3 + 12 * DEM_C4

 + 30 * SUP_WH1 + 25 * SUP_WH2 + 21 * SUP_WH3;

 [ VOLUME_WH1_C1]  DEM_C1 +  SUP_WH1 <= 6;

 [ VOLUME_WH1_C2]  DEM_C2 +  SUP_WH1 <= 2;

 [ VOLUME_WH1_C3]  DEM_C3 +  SUP_WH1 <= 6;

 [ VOLUME_WH1_C4]  DEM_C4 +  SUP_WH1 <= 7;

 [ VOLUME_WH2_C1]  DEM_C1 +  SUP_WH2 <= 4;

 [ VOLUME_WH2_C2]  DEM_C2 +  SUP_WH2 <= 9;

 [ VOLUME_WH2_C3]  DEM_C3 +  SUP_WH2 <= 5;

 [ VOLUME_WH2_C4]  DEM_C4 +  SUP_WH2 <= 3;

 [ VOLUME_WH3_C1]  DEM_C1 +  SUP_WH3 <= 8;

 [ VOLUME_WH3_C2]  DEM_C2 +  SUP_WH3 <= 8;

 [ VOLUME_WH3_C3]  DEM_C3 +  SUP_WH3 <= 1;

 [ VOLUME_WH3_C4]  DEM_C4 +  SUP_WH3 <= 5;

 @BND( -0.1E+31, SUP_WH1, 0); @BND( -0.1E+31, SUP_WH2, 0);

 @BND( -0.1E+31, SUP_WH3, 0);

 END

 

:

You will notice that in the dual formulation the variables from the primal model become the rows of the dual.  Similarly, the rows in the primal become the variables in the dual.

Note:The row names from the primal problem will become the variable names in the dual formulation.  For this reason, it is strongly recommended that you name all the rows in the primal model.  If a row is unnamed, then a default name will be generated for the corresponding dual variable.  The default name will consist of an underscore followed by the row's internal index.  These default names will not be very meaningful, and will make the dual formulation difficult to interpret.