在Python中求解符号布尔变量
我需要解一组符号布尔表达式,如:在Python中求解符号布尔变量,python,boolean,sympy,symbolic-math,sage,Python,Boolean,Sympy,Symbolic Math,Sage,我需要解一组符号布尔表达式,如: >>> 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))
>>> 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),因此暴力策略是不可能的。我在网上搜索发现,它具有符号操作功能(特别有用)。我该怎么做
编辑:我主要试图操纵这样的事情:
>>> from sympy import *
>>> x=Symbol('x', bool=True)
>>> y=Symbol('y', bool=True)
>>> solve(x & y, x)
这将导致未实现错误。
然后我尝试了solve(x*y,x)
它给出了[0]
(我不知道它是什么意思),solve(x*y=True,x)
导致了语法错误,solve(x*y,True,x)
和solve(x&y,True,x)
给出了属性错误。我不知道还能尝试什么
编辑(2):我也发现了,可能有用 我想我得到了(尽管它的用法还不清楚)。首先,纠正你问题中一些明显错误的地方:
solve
求解代数表达式solve(expr,x)
为x
解方程expr=0
solve(x | y=False)
等都是无效语法。在Python中,不能使用=
来表示相等。请参阅(我建议您也阅读该教程的其余部分)
- 正如我在对问题的回答中提到的,
Symbol('y',bool=True)
不起任何作用<代码>符号('x',something=True)
设置是x
的假设,但bool
不是SymPy任何部分认可的假设。只需对布尔表达式使用正则的符号('x')
正如一些评论者所指出的,您想要的是可满足的,它实现了SAT解算器<代码>可满足(expr)
告诉您expr
是否可满足,也就是说,如果expr
中的变量值使其为真。如果它是可满足的,则返回此类值的映射(称为“模型”)。如果不存在这样的映射,即,expr
是矛盾的,那么它将返回False
因此,可满足性(expr)
与求解expr=True
相同。如果要解决expr=False
,应使用satisfable(~expr)
(~
,在symphy中表示不可用)
最后,请注意,satisfable
只返回一个解,因为通常这是您想要的,而查找所有解通常非常昂贵,因为可能有多达2**n
个解,其中n
是表达式中的变量数
但是,如果要查找所有表达式,通常的技巧是在原始表达式中附加~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
为假(将&
视为在解决方案中添加额外条件)。通过这种方式迭代,您可以生成所有解决方案 你找到的解决方案有什么问题?你试过什么?我们不能做你们的评估工作。好吧,我发现了布尔变量的用法,但找到了方程的解,但如何连接这两者呢solve
假设RHS是0
,但是在这里我怎么才能把True
或False
?我想你应该对布尔表达式使用可满足的而不是solve
。@kalhartt更好。0.6.7是SymPy的一个非常旧的版本。如果satisfable
对您来说太慢,请查看其他用C编写的SAT解算器。例如picosat
,可能会很有用。这将要求您以更基本的方式(所谓的DIMACS cnf形式)来表述您的问题,但是这样的解算器几乎会立即返回解决方案,即使是非常大的问题。我应该提到,picosat
具有Python绑定,称为pycosat
。太棒了!有一件事我想补充一点,我发现只有一个解决方案对我的目的是足够的。好事情。否则,解决问题可能需要很长时间。令人惊讶的是,satisfable
并不总是解决所有变量<代码>可满足(等式(3*A-B,7)和等式(2*A+3*B,1))
给出{Eq(2*A+3*B,1):真,等式(3*A-B,7):真}
,但它不能求解A
和B
。
In [8]: satisfiable(x ^ y)
Out[8]: {x: True, y: False}
In [9]: satisfiable((x ^ y) & ~(x & ~y))
Out[9]: {x: False, y: True}