Lindo Systems
! Report generation in LINGO. (RangeReport.lng);
! Illustrates how to accesses dual prices and range analysis,
and in general, how to analyze an LP solution report.
For example, if a row of the standard solution report has a pair of zeros,
so-called snake eyes, then there may be alternative optima;
! Key words: @FORMAT, @WRAP, Alternative optima, Dual prices, LINGO, MOD function,
Parametric analysis, Range analysis, Reduced cost, Report generation,
Sensitivity analysis, Snake eyes, Solution report, Staff scheduling, Submodel;
SETS:
DAYS : REQUIRED, START;
ENDSETS
DATA:
DAYS = MON TUE WED THU FRI SAT SUN;
REQUIRED = 20 16 13 16 19 14 12;
ENDDATA
SUBMODEL STAFFIT:
! A simple 5 days on, 2 days off staffing model with wraparound;
! Minimize total number starting over all days;
MIN = @SUM( DAYS( d): START( d));
@FOR( DAYS( d):
! The @WRAP function is a variation of the MOD function;
[REQDAY] @SUM( DAYS( i) | i #LE# 5:
START( @WRAP( d - i + 1, 7))) >= REQUIRED( d)
);
ENDSUBMODEL
CALC:
@SET( 'DUALCO', 2);! Compute dual prices/reduced costs (0:No, 1:Prices, 2:+Ranges);
@SET( 'TERSEO',2); ! Output level (0:verb, 1:terse, 2:only errors, 3:none);
@SOLVE( STAFFIT);
! Write a variables section report;
@WRITE(' Variables report', @NEWLINE(1));
@WRITE(' Allowable Allowable', @NEWLINE(1));
@WRITE(' Variable Value RedCost Increase Decrease', @NEWLINE(1));
@FOR( DAYS( d):
XV = START( d); ! Primal values;
PRC = @DUAL( START( d)); ! Dual values;
RUP = @RANGEU( START( d));! Range up;
RDN = @RANGED( START( d));! Range down;
! Replace infinity by 99999;
RUP = @SMIN( RUP, 99999);
RDN = @SMIN( RDN, 99999);
@WRITE( 'START(',DAYS(d),') ', @FORMAT( XV,'7.2f'), ' ', @FORMAT( PRC, '8.3f'),
' ',@FORMAT( RUP, '10.3f'), ' ',@FORMAT( RDN, '10.3f'), @NEWLINE( 1));
);
! Write a constraints section report;
@WRITE( @NEWLINE( 1));
@WRITE(' Constraints report', @NEWLINE(1));
@WRITE(' Allowable Allowable', @NEWLINE(1));
@WRITE(' Row Slack DualP Increase Decrease', @NEWLINE(1));
@FOR( DAYS( d):
XS = @SUM( DAYS( i) | i #LE# 5: ! Primal values;
START( @WRAP( d - i + 1, 7))) - REQUIRED( d);
PRC = @DUAL( REQDAY( d)); ! Dual values;
RUP = @RANGEU( REQDAY( d));! Range up;
RDN = @RANGED( REQDAY( d));! Range down;
! Replace infinity by 99999;
RUP = @SMIN( RUP, 99999);
RDN = @SMIN( RDN, 99999);
@WRITE( ' ', DAYS( d),') ', @FORMAT( XS,'7.2f'), ' ', @FORMAT( PRC, '8.3f'),
' ',@FORMAT( RUP, '10.3f'), ' ',@FORMAT( RDN, '10.3f'), @NEWLINE( 1));
);
ENDCALC