Reputation: 23
I'm looking to satisfy a set of constraints using PuLP and I'm not exactly sure how to set up the variables to do so.
For example, how would I set up variables for the following constraint:
((x_1 < x_2) AND (x_1 < x_3)) OR ((x_1 > x_2) AND (x_1 > x_3))
A variable x_1 is either less or greater than both, x_2 and x_3.
Any help would be appreciated. Thanks!
Upvotes: 1
Views: 2265
Reputation: 16724
The constraint
((x1 <= x2) AND (x1 <= x3)) OR ((x1 >= x2) AND (x1 >= x3))
can be formulated with just one extra binary variable:
x1 <= x2 + delta*M
x1 <= x3 + delta*M
x1 >= x2 - (1-delta)*M
x1 >= x3 - (1-delta)*M
delta in {0,1}
Most advanced solvers have indicator constraints, allowing us to write this without big-M's:
delta = 0 -> x1 <= x2
delta = 0 -> x1 <= x3
delta = 1 -> x1 >= x2
delta = 1 -> x1 >= x3
delta in {0,1}
Upvotes: 4
Reputation: 33532
First a remark: there is no <
operator in Linear-programming. There is only <=
. This means: if you want strict inequalities, you will need to add some small constant epsilon!
Now let's assume your task looks like: ((x1<=x2) && (x1<=x3)) || ((x1>x2) && (x1>x3))
(>
is the logical negation of <=
here which will make this work despite the above).
Let's call (x1>x2) = z1
and (x1>x3) = z2
. Then this can be simplified to: (!z1 || z2) && (z1 || !z2)
(i used the names A and B in the link).
z1, z2
x1 <= x2 + M * z1
where M is a big constant; (z1=0) -> x1 <= x2
x1 <= x3 + M * z2
where M is another big constant; (z2=0) -> x1 <= x3
(!z1 || z2) && (z1 || !z2)
!(z1 xor z2)
, here 1-(z1 xor z2)
(look at the truth-table in the "simplified" link above ) and you can follow a very active Stackoverflow-user here to linearize the xor
:
z3
z3 <= (1-z1) + (1-z2)
z3 >= (1-z1) - (1-z2)
z3 >= (1-z2) - (1-z1)
z3 <= 2 - (1-z1) - (1-z2)
z3
is now z1 xor z2
z3 == 0
(There might be some error in the above, but the concept should be ok. With code at hands you should be able to make it work)
Upvotes: 3