我正在处理布尔函数,我只能(但安全地)假设它们作为SOP进入并且不包含任何否定(例如(A&& B& C)| |(A&& B& D))。分离的数量通常> 5,通常的连词数> 10.
因为在我的情况下计算每个变量的值很难并且结果是被认为是短暂的,所以我需要能够针对变量出现最小化所述函数。这种最小化的结果不需要是任何正常形式,并且允许任意深度嵌套。
之前问过类似的问题,SO points使用扇出最小化,卡诺图,QM或BDD的一般解决方案。在处理这些方法之前 - 这会大大夸大我的代码 - 我想仔细检查关于输入函数的先验已知事实是否不会产生使用较小但尽管不那么通用的最小化方法的可能性。
应用吸收和分配规律的AFAICS将始终提供最小的形式。是否有可能利用这些功能作为SOP而没有否定的事实?在我看来,对变量应该有一个简单的交集和并集运算的递归算法,它将产生所需的结果。
可以描述一下这个算法吗?
编辑:征求意见:对该主题做了一些研究后,在我看来,这里提出的问题等同于找到给定函数的简化BDD的最优变量排序。
背景:最小化的函数被传递到作业队列以计算所有必需变量的值。之后评估该功能。考虑应用示例:
答案 0 :(得分:1)
这是一个简单的算法:
让我们考虑一个例子:ABC + ABD
有
首先将表达式转换为2D表格(它不是k-map):
T1 T2
A 1 1
B 1 1
C 1 0
D 0 1
**begin**
**While** the table is not empty do :
**if** a row or a column have only zeros, **then**
remove it from table and continue.
**end if**
**if** there is a row or more with only ones **then**
factor the vars corresponding to the rows
and remove the rows from the table
**else**
get the rows having a max number of ones,
do their scalar prod
from the scalar prod obtained,
get the columns corresponding to zeros (terms)
and put aside the one having a min number of ones
and remove its column from the table
**end else**
**end while**
close brackets
**end**
上表的应用:
T1 T2
A 1 1
B 1 1
C 1 0
D 0 1
迭代1: 有两行只有一个,A和B,将它们排除在表中并将它们从表中删除:
表达式将从以下开始:AB(... 现在是表:
T1 T2
C 1 0
D 0 1
迭代2: 没有行只有一行。 两行的最大数量为1,其标量为0 0,两列为零,T1和T2都具有相同的数字1,无分钟,将其中一个放在一边,让我们取T1并删除它从表中: 表达式将以下式开始:AB(T1 +和T1为1 * C + 0 * D = C. 表达式将从以下开始:AB(C + ... 该表现在是:
T2
C 0
D 1
迭代3: 行C只有零,我们将删除它, 行D只有一个,我们考虑它并将其从表中删除
表达式现在是:AB(C + D(...
表现在是:空
<强> iteration4:强> 表格是空的 - &gt;
关闭括号:
表达式为AB(C + D)
它不是一个最优算法,但它不如k-maps更通用,因为它考虑到表达式是SOP而没有否定的事实
答案 1 :(得分:0)
根据您的假设,您需要在执行所需功能之前评估签名的功能。
没有先验算法可以为你做到这一点,至少在java中,因此你需要对其进行编码并继续迭代,直到你找到最通用的抽象。
在逻辑中应用了所有属性,因为您不想使用NOT操作,因此前三个对您最有用。我希望这会有所帮助。
答案 2 :(得分:0)
我会用“常识”算法来做;我不确定它是最优的,但在这种情况下很难表达“最优性”。 我假设您在评估条款的顺序中没有任何“偏好”,但这可以毫无困难地包含在程序中。
让x_1
... x_n
成为您的决策变量,y_1
... y_m
是每个prod_{i in I_j} x_i
形式的联合条款{1}}:您希望最小化的表达式是j
的{{1}}到j=1
之和。
决策变量可以先“分区”:
m
中,则无论如何都需要进行评估;先做这个
(并在之后删除集y_j
中的那些)I_j
中,则不需要对它们进行评估(也可以从集I_j
中删除它们。)如果所有子句中出现的I_j
之一为假,则表达式为false; END。
否则,目标是找到其中一个集I(j)
,例如所有x_i
都为真(或证明不存在)。
通过增加基数来订购I_j
,以最大限度地减少评估次数。
如果已将x_i
评估为true,则保留一个数组(例如I_j
),例如z_i
,否则为false。
对于该有序列表中的每个集合z_i=1
:
对于x_i
中的每个I_j
:
评估i
(如果I_j
为false);
x_i
为false,请移除z_i
以及包含x_i
的所有集。I_j
存储在i
中并继续如果此循环结束(所有1
都为真),则表达式为true。 END。
z_j
的列表为空,则表达式为false。 END。x_i
。它的优点是实现起来非常简单,我相信它应该非常有效。
答案 3 :(得分:0)
从复杂的角度来看,我认为有一些部分相关的结果似乎表明这个问题很难。
根据"On the Readability of Monotone Boolean Formulae" by Elbassioni, Makino, & Rauf (pdf link), ,很难确定CNF或DNF中的布尔公式是否可以重写为公式,其中每个变量最多出现k次(对于k> = 2)。请注意,此结果与问题陈述不匹配,因为原始公式不是单调的(即:可能包含否定)。
根据"Complexity of DNF and Isomorphism of Monotone Formulas" by Goldsmith, Hagen, & Mundelhenk (pdf link),计算任意单音布尔函数的最小DNF是NP难的。此结果不完全匹配,因为DNF中未给出原始公式,并且输出公式仅限于DNF。