【问题标题】:Solving Symbolic Boolean variables in Python在 Python 中求解符号布尔变量
【发布时间】:2013-11-11 00:39:39
【问题描述】:

我需要解决一组符号布尔表达式,例如:

>>> solve(x | y = False)
(False, False)

>>> solve(x & y = True)
(True, True)

>>> solve (x & y & z = True)
(True, True, True)

>>> solve(x ^ y = False)
((False, False), (True, True))

此类变量的数量很大(~200),因此暴力策略是不可能的。我在网上搜索,发现SympySage 具有符号操作能力(特别是thisthis 可能有用)。我该怎么做?

编辑:我主要试图操纵这样的事情:

>>> from sympy import *

>>> x=Symbol('x', bool=True)

>>> y=Symbol('y', bool=True)

>>> solve(x & y, x)

导致NotImplementedError。 然后我尝试了solve(x * y, x),它给出了[0](我不知道这是什么意思),solve(x * y = True, x) 导致了SyntaxErrorsolve(x * y, True, x)solve(x & y, True, x) 给出了AttributeError。我不知道还能尝试什么!

编辑(2):我还找到了this,可能有用!

【问题讨论】:

  • 您找到的解决方案有什么问题?你试过什么?我们不能做你的评估工作。
  • 好的,我找到this 说明使用布尔变量,但找到方程的解here,但是如何连接这两者? solve 假设 RHS 是 0,但在这里我该如何输入 TrueFalse
  • 我认为你想使用satisfiable 而不是solve 来作为this link 的布尔表达式。
  • @kalhartt this link 更好。 0.6.7 是 SymPy 的一个非常老的版本。

标签: python boolean sympy symbolic-math sage


【解决方案1】:

首先,纠正您的问题中明显错误的一些事情:

  • solve 求解代数表达式。 solve(expr, x) 求解 x 的方程 expr = 0。

  • solve(x | y = False) 等是无效的语法。在 Python 中,您不能使用 = 来表示相等。请参阅http://docs.sympy.org/latest/tutorial/gotchas.html#equals-signs(我建议您也阅读该教程的其余部分)。

  • 正如我在回答another 问题时提到的,Symbol('y', bool=True) 什么都不做。 Symbol('x', something=True)x 上设置is_something 假设,但bool 不是SymPy 的任何部分认可的假设。只需将常规 Symbol('x') 用于布尔表达式即可。

正如一些评论者所说,你想要的是 satisfiable,它实现了一个 SAT 求解器。 satisfiable(expr) 告诉您 expr 是否可满足,也就是说,expr 中的变量是否存在使其正确的值。如果它是可满足的,它会返回这些值的映射(称为“模型”)。如果不存在这样的映射,即expr 是矛盾的,则返回False

因此,satisfiable(expr) 与求解 expr = True 相同。如果要解决expr = False,则应使用satisfiable(~expr)(SymPy 中的~ 表示不是)。

In [5]: satisfiable(x & y)
Out[5]: {x: True, y: True}

In [6]: satisfiable(~(x | y))
Out[6]: {x: False, y: False}

In [7]: satisfiable(x & y & z)
Out[7]: {x: True, y: True, z: True}

最后,请注意satisfiable 只返回一个解决方案,因为通常这就是您想要的全部,而找到所有解决方案通常非常昂贵,因为它们可能多达2**n,其中@ 987654348@ 是表达式中的变量数。

但是,如果您想找到所有这些,通常的技巧是在您的原始表达式后面加上~E,其中E 是前一个解决方案的合取。例如,

In [8]: satisfiable(x ^ y)
Out[8]: {x: True, y: False}

In [9]: satisfiable((x ^ y) & ~(x & ~y))
Out[9]: {x: False, y: True}

& ~(x & ~y) 表示您不想要x 为真而y 为假的解决方案(将& 视为在您的解决方案中添加额外条件)。以这种方式迭代,您可以生成所有解决方案。

【讨论】:

  • 如果 satisfiable 对您来说太慢了,请查看其他用 C 编写的 SAT 求解器。例如,picosat 可能有用。这将要求您以更基本的方式(所谓的 DIMACS cnf 形式)制定您的问题,但即使对于相当大的问题,此类求解器也会几乎立即返回解决方案。
  • 我应该提到picosat 有Python 绑定,称为pycosat
  • 太棒了!我想补充一件事,我发现只有一种解决方案足以满足我的目的。
  • 好东西。否则,可能需要很长时间才能解决您的问题。
  • 令人惊讶的是,satisfiable 并不总能解决所有变量。 satisfiable(Eq(3*A-B,7) & Eq(2*A+3*B,1)) 给出{Eq(2*A + 3*B, 1): True, Eq(3*A - B, 7): True},但它不能解决AB
【解决方案2】:

我想我得到了it(尽管它的用途还不清楚)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-09-21
    • 2020-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-15
    • 2012-06-28
    • 1970-01-01
    相关资源
    最近更新 更多