Python sympy:使用简化布尔表达式的simplify方法却得到了未简化的表达式。

6

我正在尝试使用sympy简化布尔表达式,但是我遇到了一个问题:

from sympy.logic import simplify_logic,to_cnf,to_dnf
from sympy import Symbol,S

# Simplified to: 
#'deputy | mayor | (city & director) | (city & manager) | (director & investment & of)'
# Which seems as non simplifed expression
str(simplify_logic(eval('(city&manager)|(city&director)|(deputy)|(mayor)|(director&of&investment)')))

但是这个:
# Simplified to: 
# 'sales & (director | manager)'
# Which is simplified!
str(simplify_logic(eval('(sales&manager)|(sales&director)')))

如何简化第一个表达式?

谢谢!

编辑:通过简化,我指的是使用最少数量的运算符来表达。

注:所有单词都被定义为符号:

for word in words:
    vars()[word]=Symbol(word)
1个回答

1

根据问题,我猜你期望的结果可能是这样的:

'(city&(manager|director))|(deputy)|(mayor)|(director&of&investment)'

当深入研究 simplify_logic 函数时,我们会看到 form 参数:

字符串('cnf' 或 'dnf')或 None (默认值)。 如果是'cnf' 或 'dnf',则返回相应正常形式中最简单的表达式;如果是 None,则根据参数最少的形式返回答案(默认情况下为 CNF)。

所以,基本上发生的是输入的表达式被转换为 DNFCNF 形式。
在我们的情况下,由于参数更少,表达式被转换为 DNF 形式。
回到起点 - 我们期望得到的表达式不是有效的 DNFCNF 形式,因此我们无法得到它。
因为DNF是AND的OR,而子表达式(city&(manager|director))不满足此条件(在managerdirector之间有OR)。但是,另一个表达式被简化为:
sales & (director | manager)

因为这是一个有效的CNF表单。

通过最小化布尔函数来“简化”

通常,简化算法并不是最小化操作数的数量,而是最小化运算符(逻辑门)的数量,这通常意味着更短的表达式(有时甚至更长)。

以下是用于布尔函数最小化的一些算法:

  1. 卡诺图(警告:它不适用于超过六个输入变量,并且仅对最多四个变量实用)
  2. 奎因-麦克拉斯基算法(仅适用于具有有限输入变量和输出函数的函数)

sympy提供了SOPform(最小和积形式)和POSform(最小积和形式)的实现。

  1. Espresso算法

还有一个工具Espresso逻辑最小化,包含在pyeda中:

使用espresso_exprs函数最小化多个表达式的示例用法:

>>> f1 = Or(~a & ~b & ~c, ~a & ~b & c, a & ~b & c, a & b & c, a & b & ~c)
>>> f2 = Or(~a & ~b & c, a & ~b & c)
>>> f1m, f2m = espresso_exprs(f1, f2)
>>> f1m
Or(And(~a, ~b), And(a, b), And(~b, c))
>>> f2m
And(~b, c)

我同意关于“简化”的问题存在歧义,正如OP所说。我已经展示了这种“简化”形式的例子,并在后面详细解释了为什么它不符合CNF或DNF的简化要求。@OscarBenjamin - Aviv Yaniv
谢谢您的回答。有没有办法将我的表达式转换为最简形式(最少运算符数量)? - octa_JS
在@octa_JS的帖子中进行了更新和详细说明 :) - Aviv Yaniv
是的,他们使用了奎因-麦克拉斯基算法,但输入表示有点不同。我会添加这个,谢谢@OscarBenjamin。 - Aviv Yaniv
欢迎 @octa_JS :) 我想引用帖子中链接的文档,但是我必须事先警告您,如果您正在寻找的是 '(city&(manager|director))|(deputy)|(mayor)|(director&of&investment)' 这样的结果,SOP和POS都不会给您一个结果。 (该表达式不是有效的POS,SOP,CNF或DNF形式) - Aviv Yaniv
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接