我希望使用PuLP来满足一组约束,而我并不确定如何设置这些变量。
例如,我如何为以下约束设置变量:
((x_1 < x_2) AND (x_1 < x_3)) OR ((x_1 > x_2) AND (x_1 > x_3))
变量x_1小于或大于x_2和x_3。
任何帮助将不胜感激。谢谢!
答案 0 :(得分:3)
约束
((x1 <= x2) AND (x1 <= x3)) OR ((x1 >= x2) AND (x1 >= x3))
可以用一个额外的二进制变量来表示:
x1 <= x2 + delta*M
x1 <= x3 + delta*M
x1 >= x2 - (1-delta)*M
x1 >= x3 - (1-delta)*M
delta in {0,1}
大多数高级解算器都有指标约束,允许我们在没有big-M的情况下编写它:
delta = 0 -> x1 <= x2
delta = 0 -> x1 <= x3
delta = 1 -> x1 >= x2
delta = 1 -> x1 >= x3
delta in {0,1}
答案 1 :(得分:2)
首先评论一下:线性编程中没有<
运算符。只有<=
。这意味着:如果你想要严格的不等式,你需要添加一些小的常量 epsilon !
现在让我们假设您的任务如下:((x1<=x2) && (x1<=x3)) || ((x1>x2) && (x1>x3))
(>
是<=
的逻辑否定,尽管如此,这将使其工作。
我们打电话给(x1>x2) = z1
和(x1>x3) = z2
。然后,这可以是simplified到:(!z1 || z2) && (z1 || !z2)
(我在链接中使用了名称A和B)。
z1, z2
x1 <= x2 + M * z1
其中M是一个大常数; (z1=0) -> x1 <= x2
x1 <= x3 + M * z2
其中M是另一个大常数; (z2=0) -> x1 <= x3
(!z1 || z2) && (z1 || !z2)
!(z1 xor z2)
,这里是1-(z1 xor z2)
(请查看上面“简化”链接中的真值表),您可以关注非常活跃的Stackoverflow用户here线性化xor
:
z3
z3 <= (1-z1) + (1-z2)
z3 >= (1-z1) - (1-z2)
z3 >= (1-z2) - (1-z1)
z3 <= 2 - (1-z1) - (1-z2)
z3
现在是z1 xor z2
z3 == 0
(上面可能有一些错误,但概念应该没问题。手头有代码你应该可以使它工作)