semicon1.gms : Simple test of SEMICONT variables

Description

Simple test of semicont variables
We want to minimize the distance between x and xbar,
subject to x + s = 10, s semicontinuous.
Depending on how the bounds on s are set, the minimum distance
is acheived when s = 0 or s is in its nonzero range.


Small Model of Type : MIP


Category : GAMS Test library


Main file : semicon1.gms

$title Simple test of SEMICONT variables (SEMICON1,SEQ=109)

$onText
  Simple test of semicont variables
  We want to minimize the distance between x and xbar,
  subject to x + s = 10, s semicontinuous.
  Depending on how the bounds on s are set, the minimum distance
  is acheived when s = 0 or s is in its nonzero range.
$offText

$eolCom //
$if not set TESTTOL $set TESTTOL 1e-6
$if not set SLOWOK $set SLOWOK 0
scalar slowOK 'slow solves are OK: just abort.noerror in this case' / %SLOWOK% /;
scalar mchecks / 0 /;
$if not %MIPMCHECKS% == 0 mchecks = 1;

scalar failed / 0 /;
$escape =
$echo if{%=1, display '%=1 failed', '%=2'; failed=1}; > gtest.gms
$escape %

scalar
    tol       / %TESTTOL% /,
    center    / 8.9 /;

variable z;

semicont variable s;

positive variables
  pup           'penalty on x > center',
  plo           'penalty on x < center'
  x;

equations
  cost,
  bigx          'prevents big x',
  smallx        'prevents small x'
  f;


cost..  z =e= pup + plo;
bigx..  x - pup =l= center;
smallx..plo + x =g= center;
f..     x + s =e= 10;

model m / cost, bigx, smallx, f /;
m.optcr = 0.001;
m.optca = 0;
s.up = 10;

set sloVals 'lower bounds on s' /
'slo=0',
'slo=1'
'slo=1.5'
'slo=2.1'
'slo=2.8'
/;

parameter slo(sloVals) /
'slo=0'         0
'slo=1'         1
'slo=1.5'       1.5
'slo=2.1'       2.1
'slo=2.8'       2.8
/;

table levl(sloVals,*)
                s       z       pup     plo     x       cost    f
'slo=0'         1.1     0       0       0       8.9     0       10
'slo=1'         1.1     0       0       0       8.9     0       10
'slo=1.5'       1.5     .4      0       .4      8.5     0       10
'slo=2.1'       2.1     1       0       1.0     7.9     0       10
'slo=2.8'       0       1.1     1.1     0       10      0       10 ;

table marg(sloVals,*)
                s       z       pup     plo     x       cost    f
'slo=0'         0       0       1       1       0       1       0
'slo=1'         0       0       1       1       0       1       0
'slo=1.5'       1       0       1       1       0       1       -1
'slo=2.1'       1       0       1       1       0       1       -1
'slo=2.8'       -1      0       1       1       0       1       1 ;

parameter
  sl(sloVals), zl(sloVals), pupl(sloVals), plol(sloVals), xl(sloVals),
  costl(sloVals), fl(sloVals),
  sm(sloVals), zm(sloVals), pupm(sloVals), plom(sloVals), xm(sloVals),
  costm(sloVals), fm(sloVals);

sl   (sloVals) = levl(sloVals,'s');
zl   (sloVals) = levl(sloVals,'z');
pupl (sloVals) = levl(sloVals,'pup');
plol (sloVals) = levl(sloVals,'plo');
xl   (sloVals) = levl(sloVals,'x');
costl(sloVals) = levl(sloVals,'cost');
fl   (sloVals) = levl(sloVals,'f');

sm   (sloVals) = marg(sloVals,'s');
zm   (sloVals) = marg(sloVals,'z');
pupm (sloVals) = marg(sloVals,'pup');
plom (sloVals) = marg(sloVals,'plo');
xm   (sloVals) = marg(sloVals,'x');
costm(sloVals) = marg(sloVals,'cost');
fm   (sloVals) = marg(sloVals,'f');

loop {sloVals$[ord(sloVals) <= INF],
  s.lo = slo(sloVals);
  solve m using MIP minimizing z;
  display m.solvestat, m.modelstat;
  abort.noError$[slowOK and %solveStat.resourceInterrupt% = m.solvestat] 'Solve too slow';
  if {(m.solvestat = %solveStat.capabilityProblems%),
    abort$(m.modelstat <> %modelStat.noSolutionReturned%) 'bad modelstat', m.modelstat;
    // skip checks if the solver is not SEMICONT-capable
  else
$   batInclude gtest "(m.solvestat <> %solveStat.normalCompletion% or (m.modelstat <> %modelStat.optimal% and m.modelstat <> %modelStat.integerSolution%) )" "wrong status codes"
$   batInclude gtest "(abs(m.objval-z.l) > tol)" "z.l <> m.objval";

$   batInclude gtest "(abs(   s.l-   sl(sloVals)) > tol)" "   s.l <> sl";
$   batInclude gtest "(abs(   z.l-   zl(sloVals)) > tol)" "   z.l <> zl";
$   batInclude gtest "(abs( pup.l- pupl(sloVals)) > tol)" " pup.l <> pupl";
$   batInclude gtest "(abs( plo.l- plol(sloVals)) > tol)" " plo.l <> plol";
$   batInclude gtest "(abs(   x.l-   xl(sloVals)) > tol)" "   x.l <> xl";
$   batInclude gtest "(abs(cost.l-costl(sloVals)) > tol)" "cost.l <> costl";
$   batInclude gtest "(abs(   f.l-   fl(sloVals)) > tol)" "   f.l <> fl";

  if {mchecks,
$     batInclude gtest "(abs(   s.m-    sm(sloVals)) > tol)" "   s.m <> sm";
$     batInclude gtest "(abs(   z.m-    zm(sloVals)) > tol)" "   z.m <> zm";
$     batInclude gtest "(abs(   x.m-    xm(sloVals)) > tol)" "   x.m <> xm";
$     batInclude gtest "(abs(cost.m- costm(sloVals)) > tol)" "cost.m <> costm";
$     batInclude gtest "(abs(   f.m-    fm(sloVals)) > tol)" "   f.m <> fm";

$     batInclude gtest "(abs( pup.m-bigx.m  -pupm(sloVals)) > tol)" "pup.m-bigx.m <> pupm";
$     batInclude gtest "(abs( plo.m+smallx.m-plom(sloVals)) > tol)" "plo.m+smallx.m <> plom";
  };


$if set doscalar
  if (failed, option mip=convert; solve m using mip min z;);
  abort$failed 'test failed', s.lo;
  };
};