Description
In this test we attempt to solve a simple MINLP with logical functions (bool_and, bool_or, etc) in equality equations and check whether the returned solutions are feasible. This is in particular interesting for solvers that do their own handling of the model algebra. Contributor: Stefan Vigerske, April 2022
Large Model of Type : MINLP
Category : GAMS Test library
Main file : binary4.gms
$title 'tests that solvers evaluate logical expressions correctly'
$onText
In this test we attempt to solve a simple MINLP with logical functions
(bool_and, bool_or, etc) in equality equations and check whether the
returned solutions are feasible.
This is in particular interesting for solvers that do their own handling
of the model algebra.
Contributor: Stefan Vigerske, April 2022
$offText
$if not set TESTTOL $set TESTTOL 1e-6
$if not '%GAMS.minlp%' == '' $set solver %GAMS.minlp%
$if not set solver $set solver dicopt
Set i / 1*50 /;
Binary Variables x, y, w(i);
Variables z1, z2, z3, z4, z5, z6, z7, z8, z9, objvar;
Equations e1, e2, e3, e4, e5, e6, e7, e8, e9, obj;
e1.. z1 =E= x and y;
e2.. z2 =E= x eqv y;
e3.. z3 =E= x imp y;
e4.. z4 =E= not x;
e5.. z5 =E= x or y;
e6.. z6 =E= x xor y;
* something longer to check also operator nesting and unusual constant
e7.. z7 =E= (x and y) or (not (x or y)) and (x eqv (y or 42)) imp not y;
e8.. z8 =E= sand(i,w(i));
e9.. z9 =E= sor(i,w(i));
* because GAMS doesn't allow to optimize binary variables
obj.. objvar =E= x;
Model m /all/;
$onEcho > examiner2.opt
subsolver %solver%
examineSoluPoint 0
examineInitPoint 0
fCheckAll 0
fCheckPCon 1
primalFeasTol %TESTTOL%
trace conviol.csv
$offEcho
$onEcho > conviol.csv
* Trace Record Definition
* GAMS/Examiner2 link
* DummyToMakeExaminer2Work,PrimalConInfeas
$offEcho
option minlp = examiner2;
m.optfile = 1;
* let GAMS replace fixed variables by values to check handling of constants in logic expression
m.holdfixed = 1;
* min x should give 0
Solve m min objvar using minlp;
abort.noerror$(m.solvestat = %solveStat.capabilityProblems%) "Solver does not handle logical functions. Abort test.";
abort$(abs(m.objval)>%TESTTOL%) "objective value not 0";
* max x should give 1
Solve m max objvar using minlp;
abort$(abs(m.objval-1)>%TESTTOL%) "objective value not 1";
* min x w.r.t. y = 0 should give 0
y.fx = 0;
Solve m min objvar using minlp;
abort$(abs(m.objval)>%TESTTOL%) "objective value not 0";
* min x w.r.t. y = 1 should give 0
y.fx = 1;
Solve m min objvar using minlp;
abort$(abs(m.objval)>%TESTTOL%) "objective value not 0";
* min x w.r.t. x = 0, y = 1
x.fx = 0;
Solve m min objvar using minlp;
* min x w.r.t. x = 0
y.lo = 0;
Solve m min objvar using minlp;
* min x w.r.t. x = 1
x.fx = 1;
Solve m min objvar using minlp;
m.holdfixed = 0;
* fix all w to 1
w.fx(i) = 1;
Solve m min objvar using minlp;
* fix first w to 1, all other to 0
w.fx(i) = 1$(ord(i)=1);
Solve m min objvar using minlp;
* check whether primal constraint violation was above test tolerance for every solve
* (the kludge with MSG is because we have no double-quotes available inside the execute command)
* (skip on windows because the spaces in the call are confusing cmd.exe)
$if %system.filesys% == UNIX execute.checkErrorLevel "awk -v FS=, -v MSG='Violation too large in solve ' 'NR>3 {if ($2 > %TESTTOL%) {print MSG NR-3 ; exit(1);} }' conviol.csv"