使用“合并”,Minato 表示联合(算法)。您也可以从示例中看到这一点:
4 * y = { { 2^2, y } }
x = { { x } }
4 * y + x = { { 2^2, y }, { x } }
这个想法是内部集合代表产品,整个 ZDD 代表这些产品的总和,所以如果你只是在更多集合中进行 OR(也称为联合或合并),它们就会被有效地添加。
The complete summation algorithm actually just does (A xor B) + 2 * (A and B)
(recursively) which is equivalent to the familiar bitwise addition algorithm, but the xor
was written as (A or B) without (A and B)
.
That also makes it obvious why simply taking the union is OK when there are no common combinations - if A and B
is empty, A xor B
is the same as A or B
and the "carry" is zero.
The algorithms for OR, AND, XOR and BUTNOT are explained in detail in The Art of Computer Programming volume 4, section 7.1.4 (the answer to question 199 is relevant). The general idea for all of them is that they consider the two sub-graphs that represent all the sets with the variable v
and all the sets without the variable v
separately (which are both trivially found if v
is the topmost variable in one or both arguments as either the low and high children or the input itself), and then combining the result.
Union(F, G) =
if (F = ∅) return G
if (G = ∅) return F
if (F = G) return F
if (cache contains "F ∪ G" or "G ∪ F")
return cached value
if (F.v = G.v) result = MakeNode(F.v, F.lo ∪ G.lo, F.hi ∪ G.hi)
if (F.v > G.v) result = MakeNode(G.v, F ∪ G.lo, G.hi)
if (F.v < G.v) result = MakeNode(F.v, F.lo ∪ G, F.hi)
cache result as "F ∪ G"
return result
Intersect(F, G) =
if (F = ∅ or G = ∅) return ∅
if (F = G) return F
if (cache contains "F ∩ G" or "G ∩ F")
return cached value
if (F.v = G.v) result = MakeNode(F.v, F.lo ∩ G.lo, F.hi ∩ G.hi)
if (F.v > G.v) result = F ∩ G.lo
if (F.v < G.v) result = F.lo ∩ G
cache result as "F ∩ G"
return result