如何使用线性编程来解决逻辑约束

时间:2014-07-29 16:10:09

标签: optimization linear-programming lpsolve gurobi

我希望使用线性编程来解决逻辑中的以下描述。在下面的示例中,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)所需的整数约束?或者是否有任何工具可以使用布尔约束?

感谢。

3 个答案:

答案 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

顺便说一句,如果您可以访问lpsolveGurobi,请务必选择Gurobi。它是市场领导者,lpsolve的表现与大多数复杂问题相去甚远。

<强>更新

将此模型放入解算器后,我得到解c1 = 1

n1 = 1
n2 = 1
n3 = 1
b1 = 0
b2 = 1
b3 = 0

哪个有意义:c1 == 1c2 == 2c3 == 3第3条保持为真,案例c1=1是最小可能的。插入其他变量的值,我们可以看到满足所有三个约束。

答案 1 :(得分:1)

您的问题似乎结构非常有限,因此解决方案应该更容易。显然c1必须是1,2或3.

  1. 如果((n1 == n2或n3)&amp;&amp; b2)有一个解,那么c1 = 1.
  2. 否则,如果n1 == n2 xor n3)&amp;&amp; b1)有一个解决方案然后c1 = 2。
  3. 否则,如果((n1 == n2和n3)&amp;&amp; b3)有一个解,那么c1 = 3.(在原始问题中有一个错误,其中有一个假的1)。
  4. 否则,没有解决方案。
  5. 约束3很容易,因为b1,b2和b3中的每一个只使用一次:

    1. 如果(n1 == n2或n3)有一个解,那么c1 = 1,b2 = 1,b1 = b3 = 0.
    2. 否则,如果(n1 == n2 xor n3)有一个解,那么c1 = 2,b1 = 1,b2 = b3 = 0.
    3. 否则,如果(n1 == n2和n3)有一个解,则c1 = 3,b3 = 1,b1 = b2 = 0.
    4. 否则,没有解决方案。
    5. 约束2意味着n3可以从n1和n2计算:n3 = not(n1和n2),所以你需要做的就是尝试n1和n2的四种组合,为每种组合计算n3,然后检查那些条件。无需线性编程或整数编程。

答案 2 :(得分:0)

我认为你可以通过在约束编程系统中表达它来解决它,例如GECODEChoco。检查出来 - 有很多例子可以帮助你入门。