[与2013年9月27日https://codegolf.stackexchange.com/questions/12664/implement-superoptimizer-for-addition相关]
我对如何撰写superoptimizers感兴趣。特别是找到比特和的小逻辑公式。之前将此视为对codegolf的挑战,但它似乎比人们想象的要难得多。
我想编写找到最小可能命题逻辑公式的代码,以检查y二进制0/1变量的总和是否等于某个值x。让我们调用变量x1,x2,x3,x4等。在最简单的方法中,逻辑公式应该等于和。也就是说,当且仅当总和等于x时,逻辑公式应该为真。
这是一种天真的方式。假设y = 15且x = 5.选择所有3003种不同的方式来选择5个变量,并为每个变量创建一个带有这些变量的AND的新子句和剩余变量否定的AND。你最终得到3003个条款,每个条款的长度恰好为15,总费用为45054.
但是,如果您被允许在解决方案中引入新变量,那么您可以通过消除常见的子公式来减少这一点。所以在这种情况下,你的逻辑公式由y二元变量x和一些新变量组成。当且仅当y变量的总和等于x时,整个公式才是可满足的。唯一允许的运算符为and
,or
和not
。
事实证明,当x = 1时,有一个clever method来解决这个问题,至少在理论上是这样。但是,我正在寻找一种计算密集型方法来搜索小型解决方案。
How can you make a superoptimizer for this problem?
实施例。以两个变量为例,我们想要一个逻辑公式,当它们总和为1时就是True。一个可能的答案是:
(((not y0) and (y1)) or ((y0) and (not y1)))
要将新变量引入公式(例如z0
)以表示y0 and not y1
,我们可以引入新条款(y0 and not y1) or not z0
并将y0 and not y1
替换为z0
在整个配方的其余部分。当然,在这个例子中这是没有意义的,因为它使表达式更长。
答案 0 :(得分:2)
以二进制形式写下您想要的总和。首先看看最不重要的位,y0。显然, x1 xor x2 xor ... xor xn = y0 - 这是你的第一个公式。最终公式将是所需总和的每个位的公式的组合。
现在,您知道如何实现加法器吗? http://en.wikipedia.org/wiki/Adder_(electronics)。从中获取灵感,将输入分组为对/三位,计算进位,并使用它们为y1 ... yk制作公式。如果您需要进一步的提示,请告诉我。
答案 1 :(得分:1)
如果我理解您的要求,您将需要查看逻辑最小化和/或布尔函数简化的一般主题。这些参考文献主要是关于消除布尔公式中冗余的一般方法,这些方法是作为连词(“和”)的术语的分离(“或”)。
手动,标准方法称为卡诺图。以更适合计算机实现的方式表达的等效算法是Quine-McKlosky(也称为主要蕴涵方法)。最小化问题是NP难的,QM完全解决了它。
因此,我认为QM是您想要构建的“超级优化器”所需要的。
但NP-hard和精确解决方案的结合意味着QM对于大问题是不切实际的,至少是非平凡的问题。
QM Algorithm在表格中列出了联合术语(在此上下文中称为minterms),并搜索术语对之间的1位差异。这些术语可以组合,并且在不同的组合中标记为“不关心”的不同位的因子。这与2位,4位等位的子集重复。指数行为的结果是因为较大位集的组合涉及选择:从另一个中选择一个规则。因此,它本质上是一个搜索问题。
关于启发式搜索空间有很多关于启发式的文献,但却找到了不太理想的“好”解决方案。一个着名的是Espresso。然而,由于算法的改进直接转化为半导体制造中的美元,因此最好的是最好的是专有的并且保持密切。