计算表示为ROBDD数组的函数的集合的图像

时间:2011-10-15 14:16:56

标签: algorithm binary-decision-diagram

我有一组整数,表示为Reduced Ordered Binary Decision Diagram(ROBDD)(解释为一个函数,如果输入在集合中,则计算结果为true),我将称之为Domain,以及一个整数函数(我将F)表示为一个ROBDD数组(结果每位一个条目)。

现在我想为F计算域的图像。这绝对是可能的,因为它可以通过枚举域中的所有项目,应用F,并将结果插入图像来完成。但这是一个具有指数复杂性的可怕算法(在域的大小上是线性的),而我的直觉告诉我它可以更快。我一直在寻找方向:

  1. 将限制(域)应用于F
  2. 的所有位
  3. 做魔术
  4. 但第二步证明是困难的。第一步的结果包含我需要的信息(至少,我90%肯定它),但不是正确的形式。是否有一种有效的算法将其转换为“编码为ROBDD的集合”?我还需要其他方法吗?

2 个答案:

答案 0 :(得分:1)

设S(x1,x2,x3 ... xn)为集合S的指标函数,因此如果(x1,x2,... xn),则S(x1,x2 ... xn)=真是一个S的元素。让F1(x1,x2,x3 ...... xn),F2(),... Fn()成为定义F的各个函数。然后我可以问一个特定的位模式,卡,通过形成等式例如在F的图像中S()& F1()& 〜F2()用于位模式10,然后解决这个方程,我认为我可以做,因为它是一个ROBDD。

当然你想要一个通用指示器功能,它告诉我abc是否在图像中。扩展上述内容,我认为你得到S()& (a& F1()|〜& ~F1()​​)& (b& F2()| ~b& ~F2())& ...如果你然后重新排序变量,使原始的x1,x2,... xn出现在ROBDD顺序的最后,那么你应该能够修剪树以返回true,对于x1,x2,... xn的任何设置导致值为true的情况,否则返回false。

(当然你可以用空间或耐心等待重新订购工作)。

答案 1 :(得分:1)

定义两个集值函数:

N(d1...dn): The subset of the image where members start with a particular sequence of digits d0...dn. 
D(d1...dn): The subset of the inputs that produce N(d1...dn).

然后当序列为空时,我们有完整的问题:

D(): The entire domain. 
N(): The entire image.

从完整域我们可以定义两个子集:

D(0) = The subset of D() such that F(x)[1]==0 for any x in D().
D(1) = The subset of D() such that F(x)[1]==1 for any x in D().

可以递归地应用此过程以为每个序列生成D.

D(d1...d[m+1]) = D(d1...dm) & {x | F(x)[m+1]==d[m+1]}

然后我们可以确定完整序列的N(x):

N(d1...dn) = 0 if D(d1...dn) = {}
N(d1...dn) = 1 if D(d1...dn) != {}

父节点可以从两个子节点生成,直到我们生成N()。

如果在任何时候我们确定D(d1 ... dm)为空,那么我们知道 N(d1 ... dm)也是空的,我们可以避免处理那个分支。 这是主要的优化。

以下代码(在Python中)概述了该过程:

def createImage(input_set_diagram,function_diagrams,index=0):
  if input_set_diagram=='0':
    # If the input set is empty, the output set is also empty
    return '0'
  if index==len(function_diagrams):
    # The set of inputs that produce this result is non-empty
    return '1'
  function_diagram=function_diagrams[index]
  # Determine the branch for zero
  set0=intersect(input_set_diagram,complement(function_diagram))
  result0=createImage(set0,function_diagrams,index+1)
  # Determine the branch for one
  set1=intersect(input_set_diagram,function_diagram)
  result1=createImage(set1,function_diagrams,index+1)
  # Merge if the same
  if result0==result1:
    return result0
  # Otherwise create a new node
  return {'index':index,'0':result0,'1':result1}