mpec08.gms : simple MPEC unique solution LB matches integer var

Description

extremely simple MPEC model with some useful features:
 a) it has a unique solution
 b) all matched vars are lower-bounded
 c) contains an integer var

Contributor: Steve Dirkse, Sep 2013


Small Model of Type : MPEC


Category : GAMS Test library


Main file : mpec08.gms

$title simple MPEC unique solution LB matches integer var (MPEC08,SEQ=619)

$onText
  extremely simple MPEC model with some useful features:
   a) it has a unique solution
   b) all matched vars are lower-bounded
   c) contains an integer var

Contributor: Steve Dirkse, Sep 2013
$offText

$if not set TESTTOL $set TESTTOL 1e-4

scalars
  tol / %TESTTOL% /
  c1  / -1.5 /
  c2  / -3 /
  ;
positive variables x1, x2;
integer variable y / lo 0,  up 10 /;
free variable z;
equation f1, f2, o;

f1 .. 2*x1 +   x2 + y + c1 =N= 0;
f2 ..   x1 + 2*x2 + y + c2 =G= 0;
o  .. sqr(x1-2) + sqr(x2-2) + sqr(y-2) =E= z;

model m / f1.x1, f2.x2, o /;

scalars r1, r2;
file log / '' /;


* -----------------------------------------------------------------

solve m using rmpec min z;

if {(m.solvestat = %solveStat.capabilityProblems%),
  abort$[m.modelstat <> %modelStat.noSolutionReturned%] 'Wrong status codes',
    m.solvestat, m.modelstat;
  abort.noerror 'no solution, no point in checking further';
else
  abort$[not((m.solvestat = %solveStat.normalCompletion%) and (m.modelstat = %modelStat.optimal% or
              m.modelstat = %modelStat.locallyOptimal% or m.modelstat = %modelStat.feasibleSolution%))] 'Wrong status codes',
    m.solvestat, m.modelstat;
};

r1 = 2*x1.l +   x2.l + y.l + c1;
r2 =   x1.l + 2*x2.l + y.l + c2;
putclose log
 ' ' /
 '** RMPEC: y = ', y.L:6:2 /
 'F1 := ', r1:6:2, '  perp x1 ', x1.lo:8:2, ' <= ', x1.L:6:2 ' <= ', x1.up:6:2 /
 'F2 := ', r2:6:2, '  perp x2 ', x2.lo:8:2, ' <= ', x2.L:6:2 ' <= ', x2.up:6:2 /
 ' ' / ;

abort$(abs(x1.l-0  ) > tol) 'var x1.l should be 0'  , x1.l;
abort$(abs(x2.l-0.8) > tol) 'var x2.l should be 0.8', x2.l;
abort$(abs( y.l-1.4) > tol) 'var  y.l should be 1.4',  y.l;
abort$(abs( z.l-5.8) > tol) 'var  z.l should be 5.8',  z.l;

abort$(abs(f1.l-0.7) > tol) 'equ f1.l should be 0.7', f1.l;
abort$(abs(f2.l-3.0) > tol) 'equ f2.l should be 3.0', f2.l;
abort$(abs( o.l-0  ) > tol) 'equ  o.l should be 0'  ,  o.l;


* -----------------------------------------------------------------

solve m using mpec min z;

if {(m.solvestat = %solveStat.capabilityProblems%),
  abort$[m.modelstat <> %modelStat.noSolutionReturned%] 'Wrong status codes',
    m.solvestat, m.modelstat;
  abort.noerror 'no solution, no point in checking further';
else
  abort$[not{(m.solvestat = %solveStat.normalCompletion%) and
              [m.modelstat = %modelStat.optimal% or
               m.modelstat = %modelStat.locallyOptimal% or
               m.modelstat = %modelStat.integerSolution%
              ] } ] 'Wrong status codes', m.solvestat, m.modelstat;
};

r1 = 2*x1.l +   x2.l + y.l + c1;
r2 =   x1.l + 2*x2.l + y.l + c2;
putclose log
 ' ' /
 '** MPEC: y = ', y.L:6:2 /
 'F1 := ', r1:6:2, '  perp x1 ', x1.lo:8:2, ' <= ', x1.L:6:2 ' <= ', x1.up:6:2 /
 'F2 := ', r2:6:2, '  perp x2 ', x2.lo:8:2, ' <= ', x2.L:6:2 ' <= ', x2.up:6:2 /
 ' ' / ;

abort$(abs(x1.l-0  ) > tol) 'var x1.l should be 0'  , x1.l;
abort$(abs(x2.l-1.0) > tol) 'var x2.l should be 1.0', x2.l;
abort$(abs( y.l-1.0) > tol) 'var  y.l should be 1.0',  y.l;
abort$(abs( z.l-6.0) > tol) 'var  z.l should be 6.0',  z.l;

abort$(abs(f1.l-0.5) > tol) 'equ f1.l should be 0.5', f1.l;
abort$(abs(f2.l-3.0) > tol) 'equ f2.l should be 3.0', f2.l;
abort$(abs( o.l-0  ) > tol) 'equ  o.l should be 0'  ,  o.l;