Numerical instability creating wrong result on Mixed-Integer Linear Program, bug or error? - linear-programming

I created a bug ticket for Google or-tools Java library.
I was told it is a feature of Mixed-Integer solvers.
But those results for this simple program makes me think it is a bug, since I would have to round every coefficients in order to not get a wrong result.
Program:
Minimize epsPlus + epsMinus
x, y : integer
epsPlus, epsMinus : linear
19 <= x <= 23
21 <= y <= 47
x + y <= 60
x - 0.499999999y - epsPlus + epsMinus = 0
Results with different y coefficients on the last constraint:
0.499999990 working : objective=0.000000, x=20.000000, y=40.000000, epsPlus=0.000000, epsMinus=0.000000
0.499999999 failing : objective=1.500000, x=19.000000, y=41.000000, epsPlus=0.000000, epsMinus=1.500000
0.500000000 working : objective=0.000000, x=20.000000, y=40.000000, epsPlus=0.000000, epsMinus=0.000000
Can you confirm it is not a bug?
Minimal code:
Loader.loadNativeLibraries();
MPSolver solver = MPSolver.createSolver("SCIP");
// variables
MPVariable x = solver.makeIntVar(19, 23, "x");
MPVariable y = solver.makeIntVar(21, 47, "y");
MPVariable epsPlus = solver.makeNumVar(0, Double.POSITIVE_INFINITY, "epsPlus");
MPVariable epsMinus = solver.makeNumVar(0, Double.POSITIVE_INFINITY, "epsMinus");
// constraints
MPConstraint constraint1 = solver.makeConstraint(60, 60, "constraint1");
constraint1.setCoefficient(x, 1);
constraint1.setCoefficient(y, 1);
MPConstraint constraint2 = solver.makeConstraint(0, 0, "constraint2");
constraint2.setCoefficient(x, 1);
constraint2.setCoefficient(y, -0.499999999);
constraint2.setCoefficient(epsPlus, -1);
constraint2.setCoefficient(epsMinus, 1);
// objective
MPObjective objective = solver.objective();
objective.setCoefficient(epsPlus, 1);
objective.setCoefficient(epsMinus, 1);
objective.setMinimization();
// result
solver.solve();
System.out.println(String.format("objective=%f, x=%f, y=%f, epsPlus=%f, epsMinus=%f", objective.value(), x.solutionValue(), y.solutionValue(), epsPlus.solutionValue(), epsMinus.solutionValue()));
https://github.com/google/or-tools/issues/3098
Thanks :)

Related

Linear Programming, max function (if statement)

I have a value x, which is a combination of decision variables.
I need to calculate a cost, which only triggers if x > 100. So cost = MAX(x - 100, 0) * 20.
Is there any way to do this in linear programming?
I've tried creating two binary variables (y1 & y2), in which y1 = 1 when x <= 100 & y2 = 1 when x > 100 & y1 + y2 = 1, from this website - https://uk.mathworks.com/matlabcentral/answers/693740-linear-programming-with-conditional-constraints. However, my excel solver is still giving non-linearity complaints...
Any advice on how I can fix this?
The objective
min cost = max(x-100,0)*20
can be implemented in an LP as:
min cost = y*20
y >= x - 100
x >= 0, y >= 0
There is no need for binary variables.

LPSOLVE - The model is INFEASIBLE - Why?

I'm having some trouble getting my head around why LPSOLVE can't find a solution to this.
min:;
x = 1000 ;
5000 - 1 x + 500 y = 0;
From inspection, we can see that x = 1000, and y = -8.
LPSOLVE states that the model is infeasible.
However, when inverting the sign of y, ie:
min:;
x = 1000 ;
5000 - 1 x - 500 y = 0;
LPSOLVE correctly calculates x = 1000, y = 8.
Or, as one would expect, if substituting 1000 in for x,
min:;
x = 1000 ;
5000 - 1000 + 500 y = 0;
also solves correctly, y = -8.
Can anyone shed any light on why the original snippet cannot solve?
Thanks
I found a solution. I'm not sure why it requires this (maybe someone can elaborate) but adding constraints gives the correct result:
x >= -Inf;
y >= -Inf;

Cplex for Linear Program: Are DOCplex decision variables assumed to be non-negative?

I want to write a simple LP using docplex. Suppose I have three variables: x, y, and z, the constraint is 4x + 9y - 18.7 <= z. I wrote the constraint with the code model.add_constraint(4 * x + 9 * y - 18.7 <= z). Then I set minimize z as my objective by model.minimize(z).
After solving the model, I get the result of z = 0.000. Can anyone explain the result to me? I don't understand why 0 is the optimal value of this LP. I also tried to print the details of this model:
status = optimal
time = 0 s.
problem = LP
z: 0.000; None
objective: z
constraint: 4z+9y-18.700 <= z
When I tried to model.print_solution(), the program prints z: 0.000; None where I don't understand what does "None" mean, does that mean x and y are None?
Update: Forgot to mention, I created the variable using model.continuous_var()
Indeed if you do not give a range they are non negative.
Small example out of the zoo story:
from docplex.mp.model import Model
mdl = Model(name='buses')
nbbus40 = mdl.continuous_var(name='nbBus40')
nbbus30 = mdl.continuous_var(name='nbBus30')
mdl.add_constraint(nbbus40*40 + nbbus30*30 >= 300, 'kids')
mdl.minimize(nbbus40*500 + nbbus30*400)
mdl.solve(log_output=False,)
print("nbbus40.lb =",nbbus40.lb)
for v in mdl.iter_continuous_vars():
print(v," = ",v.solution_value)
mdlv2 = Model(name='buses2')
nbbus40v2 = mdlv2.continuous_var(-2,200,name='nbBus40')
nbbus30v2 = mdlv2.continuous_var(-2,200,name='nbBus30')
mdlv2.add_constraint(nbbus40v2*40 + nbbus30v2*30 >= 300, 'kids')
mdlv2.minimize(nbbus40v2*500 + nbbus30v2*400)
mdlv2.solve(log_output=False,)
print("nbbus40v2.lb =",nbbus40v2.lb)
for v in mdlv2.iter_continuous_vars():
print(v," = ",v.solution_value)
gives
nbbus40.lb = 0
nbBus40 = 7.5
nbBus30 = 0
nbbus40v2.lb = -2
nbBus40 = 9.0
nbBus30 = -2.0

Cgal quadratic programming objective function

I am trying to minimize a function like the following:
25*x^2 + 45*x*y + y^2
and similar constraints like:
(25 + y) + 25*x <= 1
in CGAL::Quadratic_program.
To input "25x^2" and "y^2" in the objective function I can do the following:
qp.set_d(X, X, 50);
qp.set_d(Y, Y, 2);
but what about "45*x*y" ?
And how to add this constraint "(25 + y) + 25*x <= 1"
In my opinion like this, but i am not sure with 25:
qp.set_a(X, 0, 25);
qp.set_a(Y, 0, 1);
qp.set_b(0, 1);
One solution should be to update function to this form "y + 25*x <= -24"
qp.set_a(X, 0, 25);
qp.set_a(Y, 0, 1);
qp.set_b(0, -24);
(Please in constraint correct me if i am wrong)
I will be gratefull for any advices, expecially with "45*x*y" problem.
Your approach with replacing "(25 + y) + 25*x <= 1" by "y + 25*x <= -24" is obviously correct.
For objective function try:
qp.set_d(X, Y, 90);
but your matrix D:
25 22.5
22.5 1
is not positive semidefinite, so the solver may fail.

CGAL Quadratic Programming Solver, how to enter "x^4" in objective function? and in the constraints?

I am trying to minimize a function like the following:
a*x^4+b*y
and constraints like:
x^2 <= a
in CGAL::Quadratic_program.
To input "x^2" in the objective function I can do the following:
qp.set_d(X, X, 2);
but what about "x^4" ?
To add a constraint like "x<=a":
hp.set_a(X, 0, 1);
hp.set_b(0, a);
but what about "x^2 <= a" ?
The solution to solve this
kind of problems is to modify the objective function and constraints, in this case by setting z^2 = z.
//>=
Program hp(CGAL::LARGER, false, 0, false, 0);
//x+y >= -4
hp.set_a(X, 0, 1); hp.set_a(Y, 0, 1);
hp.set_b(0, -4);
//4x+2y+z^2 >= -a*b
//z^2 = z
hp.set_a(X, 1, 4); hp.set_a(Y, 1, 2); hp.set_a(Z, 1, 1);
hp.set_b(1, -a * b);
//-x + y >= −1
hp.set_a(X, 2, -1); hp.set_a(Y, 2, 1);
hp.set_b(2, -1);
//x <= 0
hp.set_a(X,3,1);
hp.set_b(3,0);
hp.set_r(3,CGAL::SMALLER);
//y <= 0
hp.set_a(Y,4,1);
hp.set_b(4,0);
hp.set_r(4,CGAL::SMALLER);
//objective function
//min a*x^2 + b*y + z^4
//z^2 = z
//min a*x^2 + b*y + z^2
hp.set_d(X, X, 2 * a); //2D
hp.set_c(Y, b);
hp.set_d(Z, Z, 2); //2D
// solve the program
Solution s = CGAL::solve_quadratic_program(hp, ET());
assert(s.solves_quadratic_program(hp));
From the given link:
This package lets you solve convex quadratic programs of the general
form ...
Why did you decide you can use quadratic solver to solve your power-of-four polynomial? Quadratic doesn't stand for "quadra" as a "four", it stands for a square as a "quadragon" and means power-of-two.
In short: you cannot use this tool to solve your problem.