【问题标题】:algorithm - minimizing boolean expressions算法 - 最小化布尔表达式
【发布时间】:2014-10-02 22:55:34
【问题描述】:

我正在尝试编写一段可以将布尔表达式的 LENGTH 减少到最小的代码,因此代码应该将表达式中的元素数量减少到尽可能少。现在我被困住了,我需要一些帮助=[

规则如下:布尔表达式中可以有任意数量的元素,但它只包含 AND 和 OR 运算符以及括号。

例如,如果我传入一个布尔表达式:ABC+BCD+DE,则最佳输出将是 BC(A+D)+DE,这与原来的相比节省了 2 个单位空间,因为这两个 BC 组合在一起合而为一。

我的逻辑是,我会尝试找出表达式中出现频率最高的元素,并将其分解出来。然后我递归地调用该函数对分解的表达式做同样的事情,直到它被完全分解。 但是,我怎样才能找到原始表达式中最常见的元素?也就是说,在上面的例子中,BC?似乎我必须尝试所有不同的元素组合,并找出每个组合在整个表达式中出现的次数。但这听起来真的很幼稚。 第二个

有人可以提示如何有效地做到这一点吗?甚至我可以在 Google 上搜索到的一些关键字也可以。

【问题讨论】:

  • @Li-aungYip Ya 我已经想到了,但这只是在你使用铅笔和纸的情况下,对吗?我怎样才能制作一个可以做到这一点的计算机代码?
  • 加上括号,BC(A+D)+DE 和 ABC+BCD+DE 长度相同。我现在正在解决同样的问题。这个link 在代数最小化部分稍微谈到了它。我认为它只是将布尔标识应用于公式。

标签: python algorithm math boolean


【解决方案1】:

您正在寻找的是一种最小化布尔函数的方法。这是芯片设计社区特别感兴趣的事情。一种用于您的目的的技术是 Quine-McCluskey algorithm,或者您可以使用 Li-aung Yip 在 cmets 中建议的 Karnaugh Maps

【讨论】:

  • 哎呀,比我快 12 分钟。 :)
  • 我读过一些关于 Quine-McCluskey 算法的文章,它说随着输入的变大,内存和时间呈指数增长。我正在寻找可以处理数百个输入(表达式中的文字)的东西......那么还有另一种方法吗?还是我误解了如何使用奎因的算法?谢谢!
  • @Jimster:我强烈建议您阅读链接的 Wikipedia 文章,该文章讨论了这个问题。 wiki 文章提到,Espresso minimiser 可以启发式地处理大型布尔表达式,它的扩展性比 Quine-McCluskey 好得多。
  • 正如@Li-aungYip 所说,有用于处理大型表达式的启发式方法,Espresso 是探索这些的好包。但总的来说,您想做的事情在计算上非常困难。 EDA(电子设计自动化 - 负责所有芯片设计工具)行业已经在这个和类似领域工作了很长时间,但没有快速解决方法,并且精确的算法在变量数量上呈指数级。
【解决方案2】:

对不起,我还没有阅读所有这些很酷的算法,但你问到找到公因数,所以我想到了以下内容:

import itertools
def commons(exprs):
    groups = []
    for n in range(2, len(exprs)+1):
        for comb in itertools.combinations(exprs, n):
            common = set.intersection(*map(set, comb))
            if common:
                groups.append(
                            (len(common), n, comb, ''.join(common)))
    return sorted(groups, reverse=True)

>>> exprs
['ABC', 'BCD', 'DE', 'ABCE']

>>> commons(exprs)
[(3, 2, ('ABC', 'ABCE'), 'ACB'),
 (2, 3, ('ABC', 'BCD', 'ABCE'), 'CB'),
 (2, 2, ('BCD', 'ABCE'), 'CB'),
 (2, 2, ('ABC', 'BCD'), 'CB'),
 (1, 2, ('DE', 'ABCE'), 'E'),
 (1, 2, ('BCD', 'DE'), 'D')]

函数返回一个按以下顺序排序的列表:

  1. 公因数的长度
  2. 具有此公因数的词条数

【讨论】:

  • 感谢寻找公因数的算法,我将尝试在此基础上构建一个布尔转换器。在我的情况下,当前现有的算法很难实现 =]
  • 我认为分解是不够的,你必须知道什么时候消除表达式。与使用单个因素相比,上述示例可以进一步简化。可以先转成:B(AC+CD+ACE) + DE,再转成BC(A+D+AE) + DE。然后注意A+AE是多余的,所以你终于有了BC(A+D) + DE
【解决方案3】:

使用Quine-McCluskey 算法来最小化布尔表达式。它在功能上等同于卡诺图方法,但更适合在计算机上实现。

【讨论】:

    【解决方案4】:

    您可能还想看看Espresso heuristic logic minimizer

    【讨论】:

      【解决方案5】:

      不幸的是,大多数给定的建议可能实际上并没有给@turtlesoup 他/她正在寻找的东西。 @turtlesoup 要求一种方法来最小化给定布尔表达式的字符数。大多数简化方法不会将字符数作为简化的重点。当谈到电子产品的最小化时,用户通常希望门(或零件)的数量最少。就表达式的“长度”而言,这并不总是会导致更短的表达式——大多数时候会,但并非总是如此。事实上,就长度而言,有时表达式可能会变得更大,尽管从电子学的角度来看它可能更简单(需要构建的门更少)。

      boolengine.com 是我所知道的关于数字电路布尔简化的最佳简化工具。它不允许数百个输入,但它允许 14 个,这比大多数简化工具要多得多。

      在处理电子产品时,简化程序通常会将表达式分解为乘积和形式。所以表达式'(ab)+'cd 变成了'c+'b+'a+d。 “简化”的结果需要更多字符作为表达式打印,但从电子学的角度来看更容易构建。它只需要一个 4 输入 OR 门和 3 个反相器(4 个部件)。而原始表达式需要 2 个 AND 门、2 个反相器和一个 OR 门(5 个部分)。

      把@turtlesoup 的例子给BoolEngine 后,发现BC(A+D)+DE 变成了E+D+ABC。这是一个较短的表达式,通常是。但肯定不会总是这样。

      【讨论】:

        【解决方案6】:

        这是一个实现卡诺图的小程序:http://www-ihs.theoinf.tu-ilmenau.de/~sane/projekte/karnaugh/embed_karnaugh.html

        您可以输入表达式或填写真值表。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-01-18
          • 2017-04-06
          • 2011-07-15
          • 2016-06-30
          • 2010-10-10
          • 2014-11-14
          • 2012-04-04
          • 2011-12-28
          相关资源
          最近更新 更多