Algorithm SOP形式布尔函数的最小化方法

Algorithm SOP形式布尔函数的最小化方法,algorithm,boolean-logic,algebra,boolean-operations,Algorithm,Boolean Logic,Algebra,Boolean Operations,我处理的是布尔函数,我只能(但安全地)假设它们作为SOP出现,并且不包含否定(例如(a&&B&&C)| |(a&&B&&D))。析取的数量通常大于5,其中的连接数量通常大于10 因为在我的例子中,计算每个变量的值是很困难的,并且结果被认为是短暂的,所以我需要能够最小化关于变量发生的函数。这种最小化的结果不需要任何正规形式,并且允许嵌套任意深 以前也问过类似的问题,所以可以使用扇出最小化、卡诺图、QM或BDD的一般解决方案。在处理这些方法之前——这会使我的代码大为轰动——我想再次检查一下,关于输入

我处理的是布尔函数,我只能(但安全地)假设它们作为SOP出现,并且不包含否定(例如(a&&B&&C)| |(a&&B&&D))。析取的数量通常大于5,其中的连接数量通常大于10

因为在我的例子中,计算每个变量的值是很困难的,并且结果被认为是短暂的,所以我需要能够最小化关于变量发生的函数。这种最小化的结果不需要任何正规形式,并且允许嵌套任意深

以前也问过类似的问题,所以可以使用扇出最小化、卡诺图、QM或BDD的一般解决方案。在处理这些方法之前——这会使我的代码大为轰动——我想再次检查一下,关于输入函数的先验已知事实是否不会产生使用较小但不太通用的最小化方法的可能性

应用吸收和分配定律的AFAIC将始终提供最小形式。是否有可能利用函数以SOP形式出现并且没有否定的事实?在我看来,应该有一个递归算法,对变量进行简单的交并运算,从而产生期望的结果

你能描述一下这个算法吗

编辑:征求意见:在对该主题进行了一些研究之后,我觉得这里提出的问题相当于找到给定函数的简化BDD的最佳变量顺序


背景:最小化函数被传递到作业队列,以计算所有必需变量的值。随后对该函数进行评估。考虑应用实例:

  • 输入函数(A&&B&&C)| |(A&&B&&D)可以写成A&&B&&C | | D,这样就不必对A和B进行两次求值。C和D的计算在作业队列中序列化,因为只需要证明其中一个为真
  • (A&&B&&C)| |(A&&B&&C&&D)| | |(A&&B&&X&&E)简化为A&&B&&C(X&&E))。对X&E的求值被认为更为困难,因此在队列中被置于对C求值的后面,对D的求值被丢弃

根据您的假设,在执行所需函数之前,您需要一个函数来评估签名

至少在java中,没有一种先验算法可以为您做到这一点,因此您需要对其进行编码并不断迭代,直到找到最通用的抽象

在这里,所有属性都应用于逻辑,前三个属性对您最有用,因为您不想使用NOT操作。我希望这能有所帮助。

我会用“常识”算法;我不确定它是否最优,但在这种情况下,“最优”很难表达。 我假设您在评估条款的顺序上没有任何“偏好”,但这可以毫无困难地包括在程序中

x\u 1
..
x\u n
作为你的决策变量,
y\u 1
..
y\u m
作为形式为
prod\u{i in i\u j}.x\u i
的连词从句,对于每个
j
:你希望最小化的表达式是
j=1
m
的总和

可以首先“划分”决策变量:

  • 如果它们出现在所有
    I_j
    中,则仍需对其进行评估;先做这个 (然后从集合
    I_j
    中删除)
  • 如果它们没有出现在集合
    I_j
    中,则不需要对它们进行评估(也从集合
    I(j)
    中删除它们)
如果出现在所有子句中的
x_i
之一为false,则表达式为false;结束

否则,目标是找到一个集合
I_j
,例如所有
x_I
都是真的(或者证明不存在)

通过增加基数对
I_j
排序,以最小化求值次数。 如果
x_i
已计算为true,则保留一个数组(例如
z_i
),例如
z_i=1
。 对于该有序列表中的每个集合
ij

对于
i_j
中的每个
i

  • 评估
    x_i
    (如果
    z_i
    为假)

    • 如果
      x_i
      为false,则删除
      i_j
      和包含
      i
      的所有集合
    • 如果为真,则将
      1
      存储在
      z_j
      中并继续
  • 如果此循环结束(所有
    xi
    均为true),则表达式为true。结束

  • 如果集合列表
    I_j
    为空,则表达式为false。结束
  • 否则,请转到下一个
    I_j

它的优点是实现起来非常简单,我相信它应该非常有效。

这里有一个简单的算法:

我们考虑一个例子:ABC+ABD < /P> 有

  • 两个术语T1=ABC和T2=ABD
  • 4个变量A、B、C和D
首先将表达式转换为二维表(它不是k映射):


适用于上表:

    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 
    T2  
C   0
D   1 
迭代2: 没有只有一行的行。 两行的最大值为1,它们的标量prod为0,两列的值为0,T1和T2的值均为1,无min,将其中一行放在一边,将T1从表中删除: 表达式将以:AB(T1+开始,T1是1*C+0*D=C 表达式将以:AB(C+。。。 现在的表格是:

    T1  T2  
C   1   0
D   0   1 
    T2  
C   0
D   1