我希望使用线性编程来解决逻辑中的以下描述。在下面的示例中,n1, n2, n3, b1, b2, b3
是布尔变量。
目标是尽量减少c1
。
以下是约束:
约束1:((n1==n2 xor n3) && c1==2 && b1 ) || ( (n1== n2 or n3) && c1==1 && b2 ) || (( n1 == n2 and n3) 1&& c1==3 && b3)
约束2:n1 && n2== not n3
约束3:only one of b1, b2, b3 is true
我是否可以将这些逻辑约束编码为线性编程工具(如Gurobi或lpsolve)所需的整数约束?或者是否有任何工具可以使用布尔约束?
感谢。
答案 0 :(得分:3)
可以使用混合整数编程(不是线性编程)但是很麻烦。让我们从简单的开始:
约束2 :
n1 + n2 = 1 - n3
约束3 :
b1 + b2 + b3 = 1 (if at most one of them is true then change = to <=)
约束1 :
约定:我使用y
来表示布尔变量,使用z
来表示连续的非负变量。我还假设&&
和AND
以及||
和OR
之间没有区别。
诀窍是将其分解成碎片并将每个碎片定义为单独的变量..
y1 := n1==n2 --> ((y1 xor n3) && c1==2 && b1 ) || ( (y1 or n3) && c1==1 && b2 ) || (( y1 and n3) 1&& c1==3 && b3)
y1 >= 1 - (n1 + n2)
y1 >= (n1 + n2) - 1
y1 <= 2 - 2n1 + n2
y1 <= 2 - 2n2 + n1
y2 := y1 xor n3 --> (y2 && c1==2 && b1 ) || ( (y1 or n3) && c1==1 && b2 ) || (( y1 and n3) 1&& c1==3 && b3)
y2 <= y1 + x3
y2 >= y1 - x3
y2 >= x3 - y1
y2 <= 2 - y1 - x3
y5 := c1==2 --> (y2 && y5 && b1 ) || ( (y1 or n3) && c1==1 && b2 ) || (( y1 and n3) 1&& c1==3 && b3)
让epsilon > 0
成为预定义的容差(如果2 - epsilon <= c1 <= 2 + epsilon
然后c1=2
)和M
是一个大数字(可能是c1
的上限) :
z3 >= c1 - 2 + epsilon*y3; z3 >= 0
z4 >= 2 - c1 + epsilon*y4; z4 >= 0
z3 <= My3
z4 <= My4
y3 + y4 + y5 = 1
y6 := y2 && y5 && b1 --> y6 || ( (y1 or n3) && c1==1 && b2 ) || (( y1 and n3) 1&& c1==3 && b3)
y6 <= y2
y6 <= y5
y6 <= b1
y6 >= y2 + y5 + b1 - 2
y7 := y1 or n3 --> y6 || ( y7 && c1==1 && b2 ) || (( y1 and n3) 1&& c1==3 && b3)
y7 >= y1
y7 >= n3
y7 <= y1 + n3
y10 := c1 == 1 --> y6 || ( y7 && y10 && b2 ) || (( y1 and n3) 1&& c1==3 && b3)
z8 >= c1 - 1 + epsilon*y8; z8 >= 0
z9 >= 1 - c1 + epsilon*y9; z9 >= 0
z8 <= My8
z9 <= My9
y8 + y9 + y10 = 1
y11 := y7 && y10 && b2 --> y6 || y11 || (( y1 and n3) 1&& c1==3 && b3)
y11 <= y7
y11 <= y10
y11 <= b2
y11 >= y7 + y10 + b2 - 2
假设1&&
是拼写错误,实际上是&&
,
y12 := ( y1 and n3) --> y6 || y11 || (y12 && c1==3 && b3)
y12 <= y1
y12 <= n3
y12 >= y1 + n3 - 1
y15 := c1==3 --> y6 || y11 || (y12 && y15 && b3)
z13 >= c1 - 3 + epsilon*y13; z13 >= 0
z14 >= 3 - c1 + epsilon*y14; z14 >= 0
z13 <= My13
z14 <= My14
y13 + y14 + y15 = 1
y16 := y12 && y15 && b3 --> y6 || y11 || y16
y16 <= y12
y16 <= y15
y16 <= b3
y16 >= y12 + y15 + b3 - 2
最后,y6 || y11 || y16
y6 + y11 + y16 >= 1
我希望这会有所帮助。为方便起见,我在下面提供了完整的数学模型。
数学模型
min c1
s.t. n1 + n2 = 1 - n3
b1 + b2 + b3 = 1
y1 >= 1 - (n1 + n2)
y1 >= (n1 + n2) - 1
y1 <= 2 - 2n1 + n2
y1 <= 2 - 2n2 + n1
y2 <= y1 + x3
y2 >= y1 - x3
y2 >= x3 - y1
y2 <= 2 - y1 - x3
z3 >= c1 - 2 + epsilon*y3; z3 >= 0
z4 >= 2 - c1 + epsilon*y4; z4 >= 0
z3 <= My3
z4 <= My4
y3 + y4 + y5 = 1
y6 <= y2
y6 <= y5
y6 <= b1
y6 >= y2 + y5 + b1 - 2
y7 >= y1
y7 >= n3
y7 <= y1 + n3
z8 >= c1 - 1 + epsilon*y8; z8 >= 0
z9 >= 1 - c1 + epsilon*y9; z9 >= 0
z8 <= My8
z9 <= My9
y8 + y9 + y10 = 1
y11 <= y7
y11 <= y10
y11 <= b2
y11 >= y7 + y10 + b2 - 2
y12 <= y1
y12 <= n3
y12 >= y1 + n3 - 1
z13 >= c1 - 3 + epsilon*y13; z13 >= 0
z14 >= 3 - c1 + epsilon*y14; z14 >= 0
z13 <= My13
z14 <= My14
y13 + y14 + y15 = 1
y16 >= y12
y16 >= y15
y16 >= b3
y16 >= y12 + y15 + b3 - 2
y6 + y11 + y16 >= 1
y1, ..., y16, b1, b2, b3, n1, n2, n3 binary
z3, z4, z8, z9, z13, z14 >= 0
顺便说一句,如果您可以访问lpsolve
和Gurobi
,请务必选择Gurobi
。它是市场领导者,lpsolve
的表现与大多数复杂问题相去甚远。
<强>更新强>
将此模型放入解算器后,我得到解c1 = 1
和
n1 = 1
n2 = 1
n3 = 1
b1 = 0
b2 = 1
b3 = 0
哪个有意义:c1 == 1
或c2 == 2
或c3 == 3
第3条保持为真,案例c1=1
是最小可能的。插入其他变量的值,我们可以看到满足所有三个约束。
答案 1 :(得分:1)
您的问题似乎结构非常有限,因此解决方案应该更容易。显然c1必须是1,2或3.
约束3很容易,因为b1,b2和b3中的每一个只使用一次:
约束2意味着n3可以从n1和n2计算:n3 = not(n1和n2),所以你需要做的就是尝试n1和n2的四种组合,为每种组合计算n3,然后检查那些条件。无需线性编程或整数编程。
答案 2 :(得分:0)