binary LP vs. integer LP - linear-programming

I wonder why there is a difference between the following linear programs. They are written in the LP file format. I would assume that x=1 would be the optimal solution in both cases.
Program A:
min: x;
x >= 1;
bin x;
Output:
Value of objective function: 0
Actual values of the variables:
x 0
Program B (simulates the binary constraint with the integer constrain and two additional constrains):
min: x;
x >= 1;
x <= 1;
x >= 0;
int x;
Output:
Value of objective function: 1.00000000
Actual values of the variables:
x 1

Yes, this is a small quirk of lpSove having to do with single variable constraints.
In your Problem A, setting 'bin x' ends up overriding the constraint 'x >=1.' That is why 0 is given as the optimal solution.
From the documentation:
Note that for bounds on variables, you should not put labels before
them. This is because lp_solve then makes this an extra restriction.
If you don't put a label before single variables then lp_solve doesn't
have to create an extra row for bounds on variables, resulting in better performance.
So it is better to write:
x1 >= 1;
than
r_x1: x1 >= 1;
Note that this is only for single variables, so
myrow: x1 + x2 >= 2;
performs as well as
x1 + x2 >= 2;
In your Problem A, you have a single variable constraint. When it is not explicitly named, the 'bin' declaration overrides that constraint. As you rightly point out, if you make the constraint explicit, by naming it, then lpSolve will create a new row for x1, thus honoring the constraint and the 'bin' cannot override it.
min: x;
a: x >= 1.0;
bin x;
will give you:
Value of objective function: 1.00000000
Actual values of the variables:
x 1

Related

Converting conditional constraints to linear constraints in Linear Programming

I have two variables: x>= 0 and y binary (either 0 or 1), and I have a constant z >= 0. How can I use linear constraints to describe the following condition:
If x = z then y = 1 else y = 0.
I tried to solve this problem by defining another binary variable i and a large-enough positive constant U and adding constraints
y - U * i = 0;
x - U * (1 - i) = z;
Is this correct?
Really there are two classes of constraints that you are asking about:
If y=1, then x=z. For some large constant M, you could add the following two constraints to achieve this:
x-z <= M*(1-y)
z-x <= M*(1-y)
If y=1 then these constraints are equivalent to x-z <= 0 and z-x <= 0, meaning x=z, and if y=0, then these constraints are x-z <= M and z-x <= M, which should not be binding if we selected a sufficiently large M value.
If y=0 then x != z. Technically you could enforce this constraint by adding another binary variable q that controls whether x > z (q=1) or x < z (q=0). Then you could add the following constraints, where m is some small positive value and M is some large positive value:
x-z >= mq - M(1-q)
x-z <= Mq - m(1-q)
If q=1 then these constraints bound x-z to the range [m, M], and if q=0 then these constraints bound x-z to the range [-M, -m].
In practice when using a solver this usually will not actually ensure x != z, because small bounds violations are typically allowed. Therefore, instead of using these constraints I would suggest not adding any constraints to your model to enforce this rule. Then, if you get a final solution with y=0 and x=z, you could adjust x to take value x+epsilon or x-epsilon for some infinitesimally small value of epsilon.
So I change the conditional constraints to
if x = z then y = 0 else y = 1
Then the answer will be
x - z <= M * y;
x - z >= m * y;
where M is a large enough positive number, m is a small enough positive number.

How to convert this into a set of linear constraints?

Given a 1-dimensional array of binary variables, for example
x = [0,1,0,0,1]
I would like to create a new variable y such that y <= max(x). In other words
y = 0 only if sum(x) = 0.
y = 1 only if sum(x) > 0.
How do I convert this into a set of linear constraints?
I know this must be possible because IBM CP Optimizer Suite can handle this automatically, but I don't have access to it.
Try something simple like y <= sum(x) which will force y to zero if all the x are zero.
Then for forcing y to 1 you have several choices. You could simply add a constraint that y >= x for every variable in x, or use a big M constraint like My >= sum(x) where M is some constant which is the maximum number of variables in x that can be simultaneously equal to 1. Adding the separate constraints might give a tighter linear relaxation, especially if there are many x variables.

Linear Programming - variable that equals the sign of an expression

I am trying to write a linear program and need a variable z that equals the sign of x-c, where x is another variable, and c is a constant.
I considered z = (x-c)/|x-c|. Unfortunately, if x=c, then this creates division by 0.
I cannot use z=x-c, because I don't want to weight it by the magnitude of the difference between x and c.
Does anyone know of a good way to express z so that it is the sign of x-c?
Thank you for any help and suggestions!
You can't model z = sign(x-c) exactly with a linear program (because the constraints in an LP are restricted to linear combinations of variables).
However, you can model sign if you are willing to convert your linear program into a mixed integer program, you can model this with the following two constraints:
L*b <= x - c <= U*(1-b)
z = 1 - 2*b
Where b is a binary variable, and L and U are lower and upper bounds on the quantity x-c. If b = 0, we have 0 <= x - c <= U and z = 1. If b = 1, we have L <= x - c <= 0 and z = 1 - 2*1 = -1.
You can use a solver like Gurobi to solve mixed integer programs.
For k » 1 this is a smooth approximation of the sign function:
Also
when ε → 0
These two approximations haven't the division by 0 issue but now you must tune a parameter.
In some languages (e.g. C++ / C) you can simply write something like this:
double sgn(double x)
{
return (x > 0.0) - (x < 0.0);
}
Anyway consider that many environments / languages already have a sign function, e.g.
Sign[x] in Mathematica
sign(x) in Matlab
Math.signum(x) in Java
sign(1, x) in Fortran
sign(x) in R
Pay close attention to what happens when x is equal to 0 (e.g. the Fortran function will return 1, with other languages you'll get 0).

How do I encode Manhattan distance in Mixed Integer Programming

Lets have two points, (x1, y1) and (x2,y2)
dx = |x1 - x2|
dy = |y1 - y2|
D_manhattan = dx + dy where dx,dy >= 0
I am a bit stuck with how to get x1 - x2 positive for |x1 - x2|, presumably I introduce a binary variable representing the polarity, but I am not allowed multiplying a polarity switch to x1 - x2 as they are all unknown variables and that would result in a quadratic.
If you are minimizing an increasing function of |x| (or maximizing a decreasing function, of course),
you can always have the aboslute value of any quantity x in a lp as a variable absx such as:
absx >= x
absx >= -x
It works because the value absx will 'tend' to its lower bound, so it will either reach x or -x.
On the other hand, if you are minimizing a decreasing function of |x|, your problem is not convex and cannot be modelled as a lp.
For all those kind of questions, it would be much better to add a simplified version of your problem with the objective, as this it often usefull for all those modelling techniques.
Edit
What I meant is that there is no general solution to this kind of problem: you cannot in general represent an absolute value in a linear problem, although in practical cases it is often possible.
For example, consider the problem:
max y
y <= | x |
-1 <= x <= 2
0 <= y
it is bounded and has an obvious solution (2, 2), but it cannot be modelled as a lp because the domain is not convex (it looks like the shape under a 'M' if you draw it).
Without your model, it is not possible to answer the question I'm afraid.
Edit 2
I am sorry, I did not read the question correctly. If you can use binary variables and if all your distances are bounded by some constant M, you can do something.
We use:
a continuous variable ax to represent the absolute value of the quantity x
a binary variable sx to represent the sign of x (sx = 1 if x >= 0)
Those constraints are always verified if x < 0, and enforce ax = x otherwise:
ax <= x + M * (1 - sx)
ax >= x - M * (1 - sx)
Those constraints are always verified if x >= 0, and enforce ax = -x otherwise:
ax <= -x + M * sx
ax >= -x - M * sx
This is a variation of the "big M" method that is often used to linearize quadratic terms. Of course you need to have an upper bound of all the possible values of x (which, in your case, will be the value of your distance: this will typically be the case if your points are in some bounded area)

Multiple condition clause in C/ C++

My aim is to get two numbers and perform an corresponding to the values they hold:
For ex.. Let the vars be x and y.
I need to compute the value of another var z, as follows:
z = x + y // if x = y = 1
z = x - y // if x = 0 and y = 1
Since i need to use it several times, it would not be efficient to use if else within a loop.
What i basically require is like a macro.... preferably using #define., like if it were to be used once:
#define x + y 1 replaces x+y with 1, but does not depend on the values of x and/or y
Is there any way I could replace x+y with 1, x-y with 0 and so on...
You cannot know the values of x and y until runtime, so there is nothing you can do but use an if like you were going to and think of the math that will require the fewest operations (taking into account that 1 = subtraction = addition < multiplication < division usually).
If I misunderstood and you simply want to replace x + y with 1 and x - y with 0, you can just replace them by hand or via find and replace.
If the vars are integers/any other primitive type you can't improve the performance, since the compile will usually translate it one assembly code line. such as sub eax, ebx
Anyhow, as mentioned before, you can't do it on compile time since x,y values are not known at compile time.
you can hint the compiler to save x and y on a register using the register keyword, which will save the variables on the CPU registers in order to preform faster calculations.