Joh*_*rts 2 algorithm boolean-logic boolean cad boolean-expression
我正在尝试编写一个程序,该程序需要计算处理布尔函数的特定值。给定一个单输出布尔函数 f,由覆盖 F 给出,假设我将函数的密度定义为函数值为 1 的所有输入向量的分数。
例如,假设我传入给定的函数 f(a, b, c),它由 cover F = ab'+c' 定义。该函数有 5 个 ON-set minterms,总共 8 个 minterms,因此其密度为 d(f) = 5/8 = 0.625。应该注意的是,立方体 ab' 覆盖了 2 个最小项,立方体 c' 覆盖了 4 个最小项,但是这些最小项之一被两个立方体覆盖。
谁能想到一个好的算法来处理这个问题?我强烈怀疑最好以递归方式表达,但我无法确定有效的东西。
坏消息:永远快速的算法没有希望。
即,这个问题:
给定一个合取范式(和的乘积)的布尔公式,确定是否存在自由变量的赋值,使得公式产生真
是 NP 完全的。这意味着如果你找到一个多项式时间算法来解决它,你也可以在多项式时间内解决一些世界上最难的问题(背包问题、旅行商问题、哈密顿循环问题等等)。没有人真的期望这是可能的。
这个问题实际上等价于这个问题:
给定一个析取范式(乘积之和)的布尔公式,判断它的密度是否为 100%
好消息:
输入大小可能非常小。在三个变量中,您并不真正关心速度。在 30 个输入变量时,您仍然更有可能耗尽内存(使用某些算法),而不是运行时间长得无法忍受。
算法#1:O(2^v*i)时间,几行代码,v=变量数量;i=输入的长度。
A & !A),则将其删除。density = [#covered terms]/[#terms]如果你想跑得更快,你需要希望有一个好的输入。您可以尝试使用二元决策图 (BDD) 对当前编码的最小项集进行编码,并在从输入中添加子句时尝试更新二元决策图。
二进制决策图是一个根向无环图,使得每个节点是一个判决节点(测试单个可变,然后采取任一假分支或真分支)或叶节点(无论是true或false)。例如,XOR可以用这个二元决策图表示:
|
A
/ \
/ \
B B
/ \ / \
0 1 1 0
Run Code Online (Sandbox Code Playgroud)
算法 #2(延迟扩展 BDD,更复杂但对于大量变量可能更快):
A & !A),则将其删除。true(仅在您来到的边缘处)
true,则用 替换共同的父true节点,并对新节点重复此测试。true
density = 0/(2^variables)(分母表示整数计算的建议比例)true或false。对于 BDD 中的每条路径
true
length是沿路径遇到的非叶节点的数量。1/(2^length)到density.