问题
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!
回答1:
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.
回答2:
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).
来源:https://stackoverflow.com/questions/22788264/linear-programming-variable-that-equals-the-sign-of-an-expression