Next Article in Journal
The Fast Detection and Identification Algorithm of Optical Fiber Intrusion Signals
Next Article in Special Issue
Space-Efficient Fully Dynamic DFS in Undirected Graphs
Previous Article in Journal
Application of Angle Related Cost Function Optimization for Dynamic Path Planning Algorithm
Previous Article in Special Issue
Sliding Suffix Tree
 
 
Font Type:
Arial Georgia Verdana
Font Size:
Aa Aa Aa
Line Spacing:
Column Width:
Background:
Article

DenseZDD: A Compact and Fast Index for Families of Sets

1
Department of Mathematical Informatics, Graduate School of Information Science and Technology, The University of Tokyo, Tokyo 113-8654, Japan
2
Graduate School of Science and Technology, Nara Institute of Science and Technology, Ikoma 630-0192, Japan
3
Department of Computational Biology and Medical Sciences, Graduate School of Frontier Sciences, The University of Tokyo, Tokyo 113-8654, Japan
4
Graduate School of IST, Hokkaido University, Sapporo 060-0808, Japan
5
Graduate School of Informatics, Kyoto University, Kyoto 606-8501, Japan
*
Author to whom correspondence should be addressed.
This paper is an extended version of our paper published in the 13th International Symposium on Experimental Algorithms (SEA 2014).
Algorithms 2018, 11(8), 128; https://doi.org/10.3390/a11080128
Submission received: 31 May 2018 / Revised: 4 August 2018 / Accepted: 9 August 2018 / Published: 17 August 2018
(This article belongs to the Special Issue Efficient Data Structures)

Abstract

:
In this article, we propose a succinct data structure of zero-suppressed binary decision diagrams (ZDDs). A ZDD represents sets of combinations efficiently and we can perform various set operations on the ZDD without explicitly extracting combinations. Thanks to these features, ZDDs have been applied to web information retrieval, information integration, and data mining. However, to support rich manipulation of sets of combinations and update ZDDs in the future, ZDDs need too much space, which means that there is still room to be compressed. The paper introduces a new succinct data structure, called DenseZDD, for further compressing a ZDD when we do not need to conduct set operations on the ZDD but want to examine whether a given set is included in the family represented by the ZDD, and count the number of elements in the family. We also propose a hybrid method, which combines DenseZDDs with ordinary ZDDs. By numerical experiments, we show that the sizes of our data structures are three times smaller than those of ordinary ZDDs, and membership operations and random sampling on DenseZDDs are about ten times and three times faster than those on ordinary ZDDs for some datasets, respectively.

1. Introduction

A Binary Decision Diagram (BDD) [1] is a graph-based representation of a Boolean function, widely used in very-large-scale integration (VLSI) logic design, verification, and so on. A BDD is regarded as a compressed representation that is generated by reducing a binary decision tree, which represents a decision-making process such that each inner node means an assignment of a 0/1-value to an input variable of a Boolean function and the terminal nodes mean its output values (0 or 1) of the function. By fixing the order of the input variables (i.e., the order of assignments of variables), deleting all nodes whose two children are identical, and merging all equivalent nodes (having the same variable and the same children), we obtain a minimal and canonical form of a given Boolean function.
Although various unique canonical representations of Boolean functions such as conjunctive normal form (CNF), disjunctive normal form (DNF), and truth tables have been proposed, BDDs are often smaller than them for many classes of Boolean functions. Moreover, BDDs have the following features: (i) multiple functions are stored by sharing common substructures of BDDs compactly; and (ii) fast logical operations of Boolean functions such as AND and OR are executed efficiently.
A Zero-suppressed Binary Decision Diagram (ZDD) [2] is a variant of traditional BDDs, used to manipulate families of sets. As well as BDDs, ZDDs have the feature that we can efficiently perform set operations of them such as Union and Intersection. Thanks to the feature of ZDDs, we can treat combinatorial item sets as a form of a compressed expression without extracting them one by one. For example, we can implicitly enumerate combinatorial item sets frequently appearing in given data [3].
Although the size of a ZDD is exponentially smaller than the cardinality of the family of sets represented by the ZDD in many cases, it may be still too large to be stored into a memory of a single server computer. Since a ZDD is a directed acyclic graph whose nodes have a label representing a variable and two outgoing arcs, we use multiple pointers to represent the structure of a ZDD, which is unacceptable for many applications including frequent item set mining [3,4].
We classify operations on ZDDs into two types: dynamic and static. A dynamic operation is one that constructs another ZDD when (one or more) ZDD is given. For example, given two families of sets as two ZDDs, we can efficiently construct the ZDD representing the union of the two families [5]. On the other hand, a static operation is one that computes a value related to a given ZDD but does not change the ZDD itself. For example, there are cases where we just want to know whether a certain set is included in the family or not, and we want to conduct random sampling, that is, randomly pick a set from the family. To support dynamic operations, we need to store the structure of ZDDs as it is, which increases the size of the representation of ZDDs. Therefore, there is a possibility that we can significantly reduce the space to store ZDDs by restricting to only static operations. To the best of the authors’ knowledge, there has been no work on representations of ZDDs supporting only static operations.
This paper proposes a succinct data structure of ZDDs, which we call DenseZDDs, which support only static operations. The size of ZDDs in our representation is much smaller than an existing representation [6], which fully supports dynamic operations. Moreover, DenseZDD supports much faster membership operations than the representation of [6]. Experimental results show that the sizes of our data structures are three times smaller than those of ordinary ZDDs, and membership operations and random sampling on DenseZDDs are about ten times and three times faster than those on ordinary ZDDs for some datasets, respectively.
This paper is an extended version of the paper published at the 13th International Symposium on Experimental Algorithms held in 2014 [7]. The main updates of this paper from the previous version are as follows: (i) we propose algorithms for counting and fast random sampling on DenseZDD; (ii) we propose a static representation of a variant of ZDDs called Sequence BDD; and (iii) we conduct more experiments on new large data sets using algorithms (including new proposed ones). Note that our technique can be directly applied to reduce the size of traditional BDDs as well as ZDDs.
The organization of the paper is as follows. In Section 2, we introduce our notation and data structures used throughout this paper. In Section 3, we propose our data structure DenseZDD and show the algorithms to convert a given ZDD to a DenseZDD. In Section 4, we show how to execute ZDD operations on a DenseZDD. In Section 5, we study the space complexities of DenseZDD and the time complexities of operations discussed in Section 4. In Section 6, we show how to implement dynamic operations on a DenseZDD. In Section 7, we show how to apply our technique to decision diagrams for sets of strings. In Section 8, we show results of experiments for real and artificial data to evaluate construction time, search time and compactness of DenseZDDs.

2. Preliminaries

Let e 1 , , e n be items such that e 1 < e 2 < < e n . Throughout this paper, we denote the set of all n items as U n = { e 1 , , e n } . For an itemset S = { a 1 , , a c } ( U n ) , c 0 , we denote the size of S by | S | = c . The empty set is denoted by ∅. A family is a subset of the power set of all items. A finite family F of sets is referred to as a set family (In the original ZDD paper by Minato [2], a set is called a combination, and a set family is called a combinatorial set.). The join of families F 1 and F 2 is defined as F 1 F 2 = { S 1 S 2 | S 1 F 1 , S 2 F 2 } .

2.1. Succinct Data Structures for Rank/Select

Let B be a binary vector of length u, that is, B [ i ] { 0 , 1 } for any 0 i < u . The rank value rank c ( B , i ) is defined as the number of c’s in B [ 0 . . i ] , and the select value select c ( B , j ) is the position of j-th c ( j 1 ) in B from the left, that is, the minimum k such that the cardinality of { 0 i k | B [ i ] = c } is j. Note that rank c ( B , select c ( B , j ) ) = j holds if j rank c ( B , u 1 ) , and then the number of c’s in B is j. The predecessor pred c ( B , i ) is defined as the position j of the rightmost c = B [ j ] in B [ 0 . . i ] , that is, pred c ( B , i ) : = max j { 0 j i | B [ j ] = c } . The predecessor is computed by pred c ( B , i ) = select c ( B , rank c ( B , i ) ) .
The Fully Indexable Dictionary (FID) is a data structure for computing rank and select on binary vectors [8].
Proposition 1 (Raman et al. [8]).
For a binary vector of length u with n ones, its FID uses log u n + O ( u log log u log u ) bits of space and computes rank c ( B , i ) and select c ( B , i ) in constant time on the Ω ( log u ) -bit word RAM.
This data structure uses asymptotically optimal space because any data structure for storing the vector uses log u n bits in the worst case. Such a data structure is called a succinct data structure.

2.2. Succinct Data Structures for Trees

An ordered tree is a rooted unlabeled tree such that children of each node have some order. A succinct data structure for an ordered tree with n nodes uses 2 n + o ( n ) bits of space and supports various operations on the tree such as finding the parent or the i-th child, computing the depth or the preorder of a node, and so on, in constant time [9]. An ordered tree with n nodes is represented by a string of length 2 n , called a balanced parentheses sequence (BP), defined by a depth-first traversal of the tree in the following way: starting from the root, we write an open parenthesis ‘(’ if we arrive at a node from above, and a close parenthesis ‘)’ if we leave from a node upward. For example, imagine the complete binary tree that consists of three branching nodes and four leaves. When we traverse the complete binary tree in the depth-first manner, the sequence of the transition is “down, down, up, down, up, up, down, down, up, down, up, up”. Then, we can encode the tree as “(, (, ), (, ), ), (, (, ), (, ), )” by replacing ‘down’ with ‘(’ and ‘up’ with ‘)’, respectively.
In this paper, we use the following operations. Let P denote the BP sequence of a tree. A node in the tree is identified with the position of the open parenthesis in P representing the node:
  • depth ( P , i ) : the depth of the node at position i. (The depth of a root is 0.)
  • preorder ( P , i ) : the preorder of the node at position i.
  • level _ ancestor ( P , i , d ) : the position of the ancestor with depth d of the node at position i.
  • parent ( P , i ) : the position of the parent of the node at position i (identical to level _ ancestor (P, i, depth ( P , i ) 1 ) ).
  • degree ( P , i ) : the number of children of the node at position i.
  • child ( P , i , d ) : the d-th child of the node at position i.
The operations take constant time.
A brief overview of the data structure is the following. The BP sequence is partitioned into equal-length blocks. The blocks are stored in leaves of a rooted tree called range min-max tree. In each leaf of the range min-max tree, we store the maximum and the minimum values of node depths in the corresponding block. In each internal node, we store the maximum and the minimum of values stored in children of the node. By using this range min-max tree, all tree operations are implemented efficiently.

2.3. Zero-Suppressed Binary Decision Diagrams

A zero-suppressed binary decision diagram (ZDD) [2] is a variant of a binary decision diagram [1], customized to manipulate finite families of sets. A ZDD is a directed acyclic graph satisfying the following. A ZDD has two types of nodes, terminal and nonterminal nodes. A terminal node v has as an attribute a value value ( v ) { 0 , 1 } , indicating whether it is the 0-terminal node or the 1-terminal node, denoted by 0 and 1 , respectively. A nonterminal node v has as attributes an integer index ( v ) { 1 , , n } called the index, and two children zero ( v ) and one ( v ) , called the 0-child and 1-child. The edge from a nonterminal to its 0-child (1-child resp.) is called the 0-edge (1-edge resp.). In the figures in the paper, terminal and nonterminal nodes are drawn as squares and circles, respectively, and 0-edges and 1-edges are drawn as dotted and solid arrows, respectively. We define triple ( v ) = index ( v ) , zero ( v ) , one ( v ) , called the attribute triple of v. For any nonterminal node v, index ( v ) is larger than the indices of its children (In ordinary BDD or ZDD papers, the indices are in ascending order from roots to terminals. For convenience, we employ the opposite ordering in this paper).We define the size of a ZDD G as the number of its nonterminals and denote it by | G | .
Definition 1 (set family represented by a ZDD).
A ZDD G = ( V , E ) rooted at a node v V represents a finite family of sets F ( v ) on U n defined recursively as follows: (1) If v is a terminal node: F ( v ) = { } if value ( v ) = 1 , and F ( v ) = if value ( v ) = 0 . (2) If v is a nonterminal node, then F ( v ) is the finite family of sets F ( v ) = ( { { e index ( v ) } } F ( one ( v ) ) ) F ( zero ( v ) ) .
The example in Figure 1 represents a family of sets F = { { 6 , 5 , 4 , 3 } , { 6 , 5 , 4 , 2 } , { 6 , 5 , 4 , 1 } , { 6 , 5 , 4 } , { 6 , 5 , 2 } , { 6 , 5 , 1 } , { 6 , 5 } , { 6 , 4 , 3 , 2 } , { 6 , 4 , 3 , 1 } , { 6 , 4 , 2 , 1 } , { 6 , 2 , 1 } , { 3 , 2 , 1 } }. A set S = { c 1 , , c } describes a path in the graph G starting from the root in the following way: At each nonterminal node with label c i , the path continues to the 0-child if c i S and to the 1-child if c i S , and the path eventually reaches the 1-terminal (0-terminal resp.), indicating that S is accepted (rejected resp).
We employ the following two reduction rules, shown in Figure 2, to compress ZDDs: (a) Zero-suppress rule: A nonterminal node whose 1-child is the 0-terminal node is deleted; (b) sharing rule: two or more nonterminal nodes having the same attribute triple are merged. By applying the above rules, we can reduce the size of the graph without changing its semantics. If we apply the two reduction rules as much as possible, then we obtain the canonical form for a given family of sets. We implement the sharing rule by using a hash table such that a key is an attribute triple and the value of the key is the pointer to the node corresponding to the attribute triple. When we want to create a new node with an attribute triple i , v 0 , v 1 , we check whether such a node has already existed or not. If such a node exists, we do not create a new node and use the node. Otherwise, we create a new node v with i , v 0 , v 1 and we register it to the hash table. After that, V and E are updated to V { v } and E { ( v , v 0 ) , ( v , v 1 ) } , respectively.
We can further reduce the size of ZDDs by using a type of attributed edges [2,10], named 0-element edges. A ZDD with 0-element edges is defined as follows. A ZDD with 0-element edges has the same property as an ordinary ZDD, except that it does not have the 1-terminal and that the 1-edge of each nonterminal node has as an attribute a one bit flag, called ∅-flag. The ∅-flag of the 1-edge of each nonterminal node v is denoted by empflag ( v ) , whose value is 0 or 1.
Definition 2 (set family represented by a ZDD with 0-element edges).
A ZDD with 0-element edges G = ( V , E ) rooted at a node v V represents a finite family of sets F ( v ) on U n defined recursively as follows: (1) If v is the terminal node (note that this means value ( v ) = 0 ): F ( v ) = ; (2) If v is a nonterminal node and empflag ( v ) = 1 , then F ( v ) is the finite family of sets F ( v ) = ( { { e index ( v ) } } ( F ( one ( v ) ) { } ) F ( zero ( v ) ) ; (3) If v is a nonterminal node and empflag ( v ) = 0 , then F ( v ) is the finite family of sets F ( v ) = ( { { e index ( v ) } } F ( one ( v ) ) ) F ( zero ( v ) ) .
In the figures in this paper, ∅-flags are drawn as small circles at the starting points of 1-edges. Throughout this paper, we always use ZDDs with 0-element edges and simply call it ZDDs. We always denote by m the number of nodes of a given ZDD. An example of a ZDD with 0-element edges is shown in Figure 3. When we use ZDDs with 0-element edges, we employ a pair v , c , v V , c { 0 , 1 } to point a node instead of only v, considering that a pair v , c represents the family of sets F = F ( v ) { } if c = 1 ; otherwise F = F ( v ) .
Table 1 summarizes operations of ZDDs. The upper half shows the primitive operations, while the lower half shows other operations that can be implemented by using the primitive operations. The operations index ( v ) , zero ( v ) , one ( v ) , topset ( v , i ) and member ( v , S ) do not create new nodes. Therefore, they are static operations. Note that the operation count ( v ) does not create any node; however, we need an auxiliary array to memorize which nodes have already been visited.

2.4. Problem of Existing ZDDs

Existing ZDD implementations (supporting dynamic operations) have the following problem in addition to the size of representations discussed in Section 1. The member ( v , S ) operation needs Θ ( n ) time in the worst case. In practice, the sizes of query sets are often much smaller than n, so an O ( | S | ) time algorithm is desirable. Existing implementations need Θ ( n ) time for the member ( v , S ) operation because it is implemented by repeatedly using the zero ( v ) operation.
For example, we traverse 0-edges 255 times when we search S = { e 1 } on the ZDD for F = { { e 1 } , , { e 256 } } . If we translate the ZDD to an equivalent automaton by using an array to store pointers (see Figure 4), we can execute the searching in O ( | S | ) time. ZDD nodes correspond to labeled edges in the automaton. However, the size of such an automaton via straightforward translation can be Θ ( n ) times larger than the original ZDD [11] in the worst case. Therefore, we want to perform member ( v , S ) operations in O ( | S | ) time on ZDDs.
Minato proposed Z-Skip Links [12] to accelerate the traversal of ZDDs of large-scale sparse datasets. Their method adds one link per node to skip nodes that are concatenated by 0-edges. Therefore, the amount of memory requirement cannot be smaller than original ZDDs. Z-Skip-Links make the membership operations much faster than using conventional ZDD operations when handling large-scale sparse datasets. However, the computation time is probabilistically analyzed only for the average case.

3. Data Structure

3.1. DenseZDD

In this subsection, we are going to show what DenseZDD is for a given ZDD Z. We define a DenseZDD for Z as D Z ( Z ) = U , M , I , which consists of the BP U of a zero-edge tree, the bit vector M to indicate dummy nodes, and the integer array I to store one-children.

3.1.1. Zero-Edge Tree

We construct the zero-edge tree from a given ZDD G as follows. First of all, we delete all the 1-edges of G. Then, we reverse all the 0-edges, that is, if there is a (directed) edge from v to w, we delete the edge and create the edge from w to v. Note that the tree obtained by this procedure is known as the left/right tree of a DAG whose nodes have two distinguishable arcs, originally used for representing a context-free grammar [13]. We also note that the obtained tree is a spanning one whose root node is the 0-terminal node. Next, we insert dummy nodes into 0-edges so that the distance from the 0-terminal to every node is index ( v ) . Specifically, for each node w that is pointed by 0-edges ( v 1 , w ) , , ( v k , w ) in G, we add c dummy nodes d 1 , , d c and edges ( w , d 1 ) , ( d 1 , d 2 ) , , ( d c 1 , d c ) and ( d b 1 , v 1 ) , , ( d b k , v k ) to the tree (and remove ( v 1 , w ) , , ( v k , w ) ), where b j = index ( v j ) index ( w ) 1 for j = 1 , , k , c = max v { v 1 , , v k } index ( v ) index ( w ) 1 and d 0 = w . If c = 0 , we add no dummy node for the 0-edges pointing at w. For example, see Figure 5.
We call the resulting tree the zero-edge tree of G and denote it by T Z . To avoid confusion, we call the nodes in T Z except for dummy nodes real nodes. We construct the BP of T Z and denote it by U. We let U be the first element of the DenseZDD triplet (described in the beginning of this section).
We define the real preorder rank of a real node v in T Z (and the corresponding node in G) as the preorder rank of v in the tree before adding dummy nodes and edges connecting nodes.
On BP U, as we will show later, introducing dummy nodes enable to simulate the index and topset operations in constant time by using the depth or level _ ancestor operation of BP. The length of U is O ( m n ) because we create at most n 1 dummy nodes per one real node. The dummy nodes make the length of U O ( n ) times larger, whereas this technique saves O ( m log n ) bits because we do not store the index of each node explicitly.
An example of a zero-edge tree and its BP are shown in Figure 6. Black circles are dummy nodes and the number next to each node is its real preorder rank.

3.1.2. Dummy Node Vector

A bit vector of the same length as U is used to distinguish dummy nodes and real nodes. We call it the dummy node vector of T Z and denote it by B D . The i-th bit is 1 if and only if the i-th parenthesis of U is ‘(’ and its corresponding node is a real node in T Z . An example of a dummy node vector is also shown in Figure 6. We construct the FID of B D and denote it by M. We let M be the second element of the DenseZDD triplet. Using M, as we will show later, we can determine whether a node is dummy or real, and compute real preorder ranks in constant time. Moreover, for a given real preorder rank i, we can compute the position of ‘(’ on U that corresponds to the node with real preorder rank i in constant time.

3.1.3. One-Child Array

We now construct an integer array to indicate the 1-child of each nonterminal real node in G by values of real preorder ranks. We call it the one-child array and denote it by C O . More formally, for  i = 1 , , m , C O [ i ] = v means the following: Let w T be the real node with real preorder rank i in T Z , w G be the node corresponding to w T in G, w G 1 be the 1-child of w G , and w T 1 be the node corresponding to w G 1 in T Z . Then, C O [ i ] = v means that the real preorder rank of w T 1 is the absolute value of v and empflag ( v ) = 0 if v > 0 ; otherwise empflag ( v ) = 1 . An example of a one-child array is shown in Figure 7.
As an implementation of C O , we use the fixed length array of integers (see e.g., [14]). We denote it by I. In I, one integer is represented by log ( m + 1 ) + 1 bits, including one bit for the ∅-flag. We let I be the third element of the DenseZDD triplet.
DenseZDD solves the problems as described in Section 2.4. The main results of the paper are the following two theorems.
Theorem 1.
A ZDD Z with m nodes on n items can be stored in 2 u + m log m + 3 m + o ( u ) bits so that the primitive operations except getnode ( i , v 0 , v 1 ) are done in constant time, where u is the number of real and dummy nodes in the zero edge tree of D Z ( Z ) .
Theorem 2.
A ZDD with m nodes on n items can be stored in O ( m ( log m + log n ) ) bits so that the primitive operations are done in O ( log m ) time except getnode ( i , v 0 , v 1 ) .
The proofs are given in Section 5. The time complexity of getnode ( i , v 0 , v 1 ) is discussed in Section 6.

3.2. Convert Algorithm

We show our algorithm to construct the DenseZDD D Z from a given ZDD G in detail. The pseudo-code of our algorithm is given in Algorithm 6. First, we describe how to build the zero-edge tree from G.
The zero-edge tree consists of all 0-edges of the ZDD, with their directions being reversed. For a nonterminal node v, we say that v is a 0 r -child of zero ( v ) . To make a zero-edge tree, we prepare a list revzero v for each node v, which stores 0 r -children of the node v. For all nonterminal nodes v, we visit v by a depth-first traversal of the ZDD and add v to revzero zero ( v ) . This is done in O ( m ) time and O ( m ) space because each node is visited at most twice and the total size of revzero v for all v is the same as the number of nonterminal nodes.
Let T be the zero-edge tree before introducing dummy nodes. Let us introduce an order of the elements in revzero v for each v in T so that the getnode operation, described later, can be executed efficiently. Note that the preorder ranks of nodes in T are determined by the order of children of every node in T.
Here, we observe the following fact. Consider a node v in T, and suppose that v has 0 r -children v 1 , , v k , which are ordered as v 1 < < v k . Let stsize ( v ) be the subtree size of a node v in T. Then, if the preorder rank of v is p, that of v i is p + j = 1 i 1 stsize ( v j ) + 1 for i = 1 , , k . Note that, even if the order of v 1 , , v i 1 is not determined (it is only determined that v i is located in the i-th position), the preorder rank of v i , p + j = 1 i 1 stsize ( v j ) + 1 , can be computed (see Figure 8).
Now, we introduce an order of the elements in revzero v for each node v. First, for each node v, we order the elements in revzero v in the descending order of their indices. If the indices of two nodes are the same, we temporarily and arbitrarily determine their order (we will change the order later). Then, we do the following procedure for i = 1 , , n . In the i-th procedure, suppose that the preorder ranks of all the nodes with index smaller than i have already been determined. We consider a node v. Let { v 1 , , v p } , { v p + 1 , , v p + q } and { v p + q + 1 , , v p + q + r } be the sets of nodes with index larger than i, equals to i, and smaller than i in revzero v , respectively. By our assumption, v p + q + 1 , , v p + q + r have already been ordered and we now determine the order of v p + 1 , , v p + q . We let the order of v p + 1 , , v p + q be the descending order of the preorder ranks of their one-children. Note that the preorder ranks of the one-children of v p + 1 , , v p + q have already been determined. Thus, since the positions of v p + 1 , , v p + q in revzero v are determined, the above observation implies that the preorder ranks of v p + 1 , , v p + q are also determined. We do it for all nodes v. After the procedure is finished, the preorder ranks of all the nodes (that is, the order of the children of nodes in T) are determined. As a result, the 0 r -children v of each node are sorted in the lexicographical order of index ( v ) , prank ( one ( v ) ) . The pseudo-code is given in Algorithm 1.
Algorithm 1 Compute_Preorder: Algorithm that computes the preorder rank prank ( v ) of each node v. Sets of nodes are implemented by arrays or lists in this code.
1:
L 0 { { 0 } , [ 0 , stsize ( 0 ) 1 ] }
2:
L 1 , , L n are lists that are empty initially.
3:
for i = 0 , , n do
               ▹ L i includes sets of nodes that have the same index
4:
    for each A , [ l , r ] L i in arbitrary order do
           ▹A is a set of nodes that have the same index and 0-child
       ▹ Note that prank of nodes with indices less than i are already computed
5:
        for each v A in descending order of prank ( o n e ( v ) ) do
6:
            prank ( v ) l ;
7:
            l l + 1 ;
8:
           for each j { j | w revzero ( v ) , j = index ( w ) } in descending order do
9:
                B { w | w revzero ( v ) , index ( w ) = j } ;
10:
                r l + sum { stsize ( w ) | w B } ;
11:
               append B , [ l , r ] to L j ;
               ▹ That is, the prank of descendants of nodes in B are in [ l , r ] .
12:
                l r + 1 ;
13:
           end for
14:
        end for
15:
    end for
16:
end for
17:
return;
To compute prank efficiently, we construct the temporary BP for the zero-edge tree. Using the BP, we can compute the size of each subtree rooted by v in T in constant time and compact space. Since we can compute the size of the subtrees in T, we can know the ranges of real preorder ranks that are assigned to the subtrees by bottom-up processing. The whole tree, the subtree rooted by the 0-terminal node, is assigned the range of preorder rank [ 0 , m ] . Let w be a node rooting a subtree that is assigned a range of real preorder ranks [ l , l + stsize ( w ) 1 ] and assume that the revzero ( w ) is sorted. Then, the real preorder rank of w is l and the subtree rooted by v j revzero ( w ) is assigned the range [ l j , l j + 1 1 ] , where l j = l j 1 + stsize ( v j ) and l 1 = l + 1 .
The DenseZDD for the given ZDD G is composed of these three data structures. We traverse T in depth-first search (DFS) order based on assigned real preorder ranks and construct the BP representation U, the dummy node vector M, and the one-child array I. The BP and dummy node vector are constructed as if dummy nodes exist. Finally, we obtain the DenseZDD D Z ( G ) = U , M , I . The pseudo-code is given in Algorithms 2 and 3.
Algorithm 2 Convert_ZDD_BitVectors ( v , p a r e n , d u m m y , o n e c h i l d ): Algorithm for obtaining the BP representation of the zero-edge tree, the dummy node vector, and the one-child array.
Input: ZDD node v, list of parentheses p a r e n , list of bits d u m m y , list of integers o n e c h i l d
1:
i = index ( v ) ;
2:
for each w revzero ( v ) in ascending order of prank ( w ) do
3:
    while i + 1 index ( w ) do
4:
        if i + 1 index ( w ) then
5:
           append ‘(’ to p a r e n , and ‘0’ to d u m m y ;
6:
            i i + 1 ;
7:
        else
8:
           append ‘)’ to p a r e n , and ‘0’ to d u m m y ;
9:
            i i 1 ;
10:
        end if
11:
    end while
12:
    append ‘(’ to p a r e n , and ‘1’ to d u m m y ;
13:
    append prank ( one ( w ) ) · ( 1 empflag ( w ) ) to o n e c h i l d ;
14:
    Convert_ZDD_BitVectors ( w , p a r e n , d u m m y , o n e c h i l d ) ;
15:
    append ‘)’ to p a r e n , and ‘0’ to d u m m y ;
16:
end for
17:
while i > index ( v ) do
18:
    append ‘)’ to p a r e n , and ‘0’ to d u m m y ;
19:
     i i 1 ;
20:
end while
21:
return;
Algorithm 3 Construct_DenseZDD (W: a set of root nodes of ZDD): Algorithm for constructing the DenseZDD from a source ZDD.
Output: DenseZDD D Z
1:
for each v W compute revzero fields for all descendants of v;
2:
compute stsize field for all 0 r -decsendants;
3:
Compute_Preorder;
4:
create empty lists p a r e n , d u m m y , o n e c h i l d ;
5:
append ‘(’ to p a r e n , and ‘0’ to d u m m y ;
6:
Convert_ZDD_BitVectors( 0 , paren, dummy, onechild);
7:
append ‘)’ to p a r e n , and ‘0’ to d u m m y ;
8:
make BP U from p a r e n ;
9:
make FID M from d u m m y ;
10:
make compressed representation I of o n e c h i l d ;
11:
return D Z U , M , I ;

4. ZDD Operations

We show how to implement primitive ZDD operations on DenseZDD D Z = U , M , I except getnode . We give an algorithm for getnode in Section 6.
We identify each node with its real preorder rank. We can convert the real preorder rank i of a node to the its position p in the BP sequence U, that is, the position of corresponding ‘(’ by p : = select 1 ( M , i ) and i : = rank 1 ( M , p ) , and vice versa. Algorithms in Table 1 are as follows:

4.1. index ( i )

Since the index of a node is the same as the depth, i.e., the distance from the 0-terminal node, of the node in the zero-edge tree T Z , we can obtain index ( i ) : = depth ( U , select 1 ( M , i ) ) .

4.2. topset ( i , d )

The node topset ( i , d ) is the ancestor of node i in T Z with index d. A naive solution is to iteratively climb up T Z from node i until we reach the node with index d. However, as shown above, the index of a node is identical to its depth. By using the power of the succinct tree data structure, we can directly find the answer by topset ( i , d ) : = rank 1 ( M , level _ ancestor ( U , select 1 ( M , i ) , d ) ) . If such a node with the index i is not reachable by traversing only 0-edges, the node obtained by topset ( i , d ) is a dummy node. We check whether the node is a dummy node or not by using the dummy node vector. If the node is a dummy node, we return the 0-terminal node.

4.3. zero ( i )

Implementing the zero operation requires a more complicated technique. Recall the insertion of dummy nodes when we construct T Z in Section 3.1. Consider the subtree in T Z induced by the set of the nodes consisting of the node i, its 0-child w, the dummy nodes d 1 , , d c between i and w, and the real nodes v 1 , , v k pointed by d 1 , , d c . Note that one of v 1 , , v k is i. Without loss of generality, v 1 has the smallest real preorder rank (highest index) among v 1 , , v k , and there are edges ( w , d 1 ) , ( d 1 , d 2 ) , , ( d c 1 , d c ) , ( d c , v 1 ) (see Figure 5). Computing zero ( i ) is equivalent to finding w. In the BP U of T Z , ’(’s corresponding to w , d 1 , d 2 , , d c 1 , d c , v 1 continuously appear, and the values of them in B D is 1 , 0 , 0 , , 0 , 0 , 1 , respectively. Noticing that the parent of i is one of w , d 1 , , d c and that the real preorder rank of a real node is obtained by rank 1 ( M , r ) if the position of the corresponding ’(’ is r in U, we obtain zero ( i ) : = rank 1 ( M , parent ( U , select 1 ( M , i ) ) ) .

4.4. one ( i )

The operation one ( i ) is quite easy. The 1-child of the node i is stored in the i-th element of the one-child array I. Note that the real preorder rank of the 1-child of i is a b s ( i ) , where a b s ( i ) is a function to get the absolute value of i. The ∅-flag of i is 1 if i 0 . Otherwise, it is 0.

4.5. count ( i )

Counting the number of sets in the family represented by the ZDD whose root is a node i, i.e.,  | F ( i ) | , is implemented by the same algorithm as counting on ordinary ZDDs. The pseudo-code is given in Algorithm 4. It requires an additional array C to store the cardinality of each node (for a node i , we call the cardinality of the family represented by the ZDD whose root is the node i the cardinality of the node i ). After we execute this algorithm, C [ i ] equals | F ( i ) { } | . The cardinalities are computed recursively. The algorithm count ( i ) is called for each node i only once in the recursion. The time complexity of count is Θ ( m ) , where m is the number of nodes.

4.6. sample ( i )

We propose two algorithms to implement sample ( i ) . The first one is the same algorithm as random sampling on ordinary ZDDs. Before executing these algorithms, we have to run the counting algorithm to prepare the array C that stores the cardinalities of nodes. The pseudo-code is given in Algorithm 5. We begin traversal from a root node of the ZDD that represents a set family F. At each node i, we decide whether or not the index of node i is included in the output set. We know that the number of the sets including index ( i ) is C [ o n e ( i ) ] . We also know that the number of the sets not including index ( i ) is C [ z e r o ( i ) ] . Then, we generate an integer r [ 0 , C [ i ] ) uniformly and randomly. If r < C [ z e r o ( i ) ] , we do not choose index ( i ) and go to zero ( i ) . Otherwise, we add index ( i ) to the output set and go to one ( i ) . We continue this process until we reach the 1-terminal node. At last, we obtain a set uniformly and randomly chosen from F. The time complexity of this algorithm is O ( n ) .
Algorithm 4 Count ( i ) : Algorithm that computes the cardinality of the family of sets represented by nodes reachable from a node i. The cardinalities are stored in an integer array C of length m, where m is the number of ZDD nodes. The initial values of all the elements in C are 0.
1:
if i = 0 then
2:
    return 0;
3:
end if
4:
if C [ i ] 0 then
5:
    return C [ i ] ;
6:
end if
7:
i 0 z e r o ( i ) ;
8:
c a r d 0 Count ( i 0 ) ;
9:
i 1 o n e ( i ) ;
10:
c a r d 1 Count ( abs ( i 1 ) ) ;
11:
c a r d c a r d 0 + c a r d 1 ;
12:
if i 1 0 then
13:
     c a r d c a r d + 1 ;
14:
end if
15:
C [ i ] c a r d ;
16:
return c a r d ;
Algorithm 5 Random_naive ( i , empflag ) : Algorithm that returns a set uniformly and randomly chosen from the family of sets that is represented by a ZDD whose root is node i. Assume that Count has already been executed. The argument empflag { 0 , 1 } means whether or not the current family of sets has the empty set. If empflag = 1 , this family has the empty set.
1:
if i = 0 then
2:
    return ∅;
3:
end if
4:
i 0 z e r o ( i ) ;
5:
i 1 o n e ( i ) ;
6:
c a r d C [ i ] + empflag ;
7:
Generate an integer in r [ 0 , c a r d ) uniformly and randomly.
8:
if r < C [ i 0 ] + empflag then
9:
    return Random_naive ( i 0 , empflag )
10:
else
11:
    if i 1 0 then
12:
         e 1 ;
13:
    else
14:
         e 0 ;
15:
    end if
16:
    return { index ( i ) } Random_naive ( a b s ( i 1 ) , e ) ;
17:
end if
The second algorithm is based on binary search. The main idea of this algorithm is that we consider multiple nodes at once whose indices are possibly chosen as the next element of the output set. The pseudo-code is given in Algorithm 6. As well as the first algorithm, we begin traversal from a root node. Note that the first element of the output set is one of the indices of the nodes that are reachable only by 0-edges from the current node. We use topset operation to decide which index of a node is chosen. Let the current node be i. We execute binary search on these nodes. As an initial state, we consider the range ( l = 1 , h = index ( i ) ] as candidates. Next, we divide this range by finding a node with index less than or equal to c = l + h + 1 / 2 . Such a node can be found by topset ( i , c ) . Recall that topset ( i , d ) : = rank 1 ( M , level _ ancestor ( U , select 1 ( M , i ) , d ) ) . It is the real preorder rank of a node whose index is less than c or equal to c. If the index of the found node is less than or equal to l, we update l by l c and repeat the execution of topset . When a node with index x, l < x h , is found, we choose either ( l , c ] or ( c , h ] as a next candidate range for further binary search. We know the cardinality of nodes with indices h, c, and l. The cardinality c a r d of the family of sets we consider now is the cardinality of the node with index h minus the cardinality of the node with index l. Then, generate a random integer r [ 0 , c a r d ) . If r is less than the cardinality of the node with index c, update h by h c . Otherwise, update l by l c . We continue this procedure until l + 1 = h . After that, we choose the index h as an element of the output set, and go to the 1-child of the node with index h. Again, we start binary search on the next nodes connected by continuous 0-edges. This algorithm stops when it reaches the 1-terminal node.
Algorithm 6 Random_bin ( i , empflag ) : Algorithm that returns a set uniformly and randomly chosen from the family of sets represented by the ZDD whose root is node i. This algorithm chooses the index by binary search on nodes linked by 0-edges.
1:
idx i index ( i ) , j 1 , idx j 1 ;
2:
c a r d j = 0 ;
3:
while idx i idx j do
4:
    if idx i = 0 then
5:
        return ∅;
6:
    end if
7:
     idx k ( idx i + idx j + 1 ) / 2 ;
8:
     k topset ( i , idx k ) ;
9:
    if j = k then
10:
         j k ;
11:
        continue;
12:
    end if
13:
    Generate an integer r [ 0 , C [ i ] + empflag c a r d j ) uniformly and randomly.
14:
    if r < C [ j ] + empflag card j then
                       ▹ ( idx j , idx k ] is chosen
15:
         i k ;
16:
         idx i idx k ;
17:
    else
                       ▹ ( idx k , idx i ] is chosen
18:
         j k ;
19:
         idx j idx k ;
20:
         card j card j + C [ k ] ;
21:
        if empflag = 1 then
22:
            card j card j 1 ;
23:
            empflag 0 ;
24:
        end if
25:
    end if
26:
end while
27:
i 1 one ( i ) ;
28:
if i 1 0 then
29:
    return { idx i } Random_bin ( a b s ( i 1 ) , 1 );
30:
else
31:
    return { idx i } Random_bin ( a b s ( i 1 ) , 0 );
32:
end if
This algorithm takes O ( log n ) time to choose one element of an output. The time complexity of this algorithm is O ( n log n ) . This looks worse than the previous algorithm. However, this can be better for set families consisting of small sets. Let s be the size of the largest sets in the family. Then, its time complexity is O ( s log n ) . Therefore, this algorithm is efficient for large data sets consisting of small sets of many items.

5. Complexity Analysis

Let the length of balanced parentheses sequence U be 2 u , where u is the number of ZDD nodes with dummy nodes. When a ZDD has m nodes and the number of items is n, u is m n in the worst case. Here, we show how to compress the BP sequence U.
We would like to decrease the space used by DenseZDD. However, we added extra data, dummy nodes, to the given ZDD. We want to bound the memory usage caused by dummy nodes. From the pseudo-code in Algorithm 2, we observe that the BP sequence U consists of at most 2 m runs of identical symbols. To see this, consider the substring of U between the positions for two real nodes. There is a run consisting of consecutive ‘)’ followed by a run consisting of consecutive ‘(’ in the substring. We compress U by using some integer encoding scheme such as the delta-code or the gamma-code [15]. An integer x > 0 can be encoded in O ( log x ) bits. Since the maximum length of a run is n, U can be encoded in O ( m log n ) bits. The range min-max tree of U has 2 m / log m leaves. Each leaf of the tree corresponds to a substring of U that contains log m runs. Then, any tree operation can be done in O ( log m ) time. The range min-max tree is stored in O ( m ( log n + log m ) / log m ) bits.
We also compress the dummy node vector B D . Since its length is 2 u 2 m n and there are only m ones, it can be compressed in m ( 2 + log m ) + o ( u ) bits by FID. The operations select 1 and rank 1 take constant time. We can reduce the term o ( u ) to o ( m ) by using a sparse array [16]. Then, the operation select 1 is done in constant time, while rank 1 takes O ( log m ) time. We call the DenseZDD whose zero-edge tree and dummy node vector are compressed dummy-compressed DenseZDD.
From the discussion in the section, we can prove Theorems 1 and 2.
Proof of Theorem 1.
From the above discussion, the BP U of the zero-edge tree costs 2 u = O ( m n ) bits, where u is the number of real nodes and dummy nodes. The one-child array needs m log m bits for 1-children and m bits for ∅-flags. Using FID, the dummy node vector is stored in m ( 2 + log m ) + o ( u ) bits. Therefore, the DenseZDD can be stored in 2 u + 3 m + 2 m log m + o ( u ) bits and the primitive operations except getnode are done in constant time because the rank 1 , select 1 , and any tree operations take constant time by Proposition 1. ☐
Proof of Theorem 2.
When we compress U, it can be stored in O ( m log n ) bits and the min-max tree is stored in O ( m ( log n + log m ) / log m ) bits. The dummy node vector can be compressed in m ( 2 + log m ) + o ( m ) bits by FID with sparse array. The time of any tree operations and the rank 1 operation is O ( log m ) . Therefore, the DenseZDD can be stored in O ( m ( log m + log n ) ) bits and the primitive operations except for getnode take O ( log m ) time because all of them use tree operations on U or rank 1 on M. ☐

6. Hybrid Method

In this section, we show how to implement dynamic operations on DenseZDD. Namely, we implement the getnode ( i , v 0 , v 1 ) operation. Our approach is to use a hybrid data structure using both the DenseZDD and a conventional dynamic ZDD. Assume that initially all the nodes are represented by a DenseZDD. Let m 0 be the number of initial nodes. In a conventional dynamic ZDD, the operation getnode ( i , v 0 , v 1 ) is implemented by a hash table indexed with the triple i , v 0 , v 1 .
We first show how to check whether the node v : = getnode ( i , v 0 , v 1 ) has already existed or not. That is, we want to find a node v such that index ( v ) = i , zero ( v ) = v 0 , one ( v ) = v 1 . If v exists in the zero-edge tree, v is one of the 0 r -children of v 0 . Consider again the subtree of the zero-edge tree rooted at v 0 and the 0 r -children of v 0 (see the right of Figure 5). Let d p be the (possibly dummy) parent of v in the zero edge tree. The parent of all the 0 r -children of v 0 with index i in the zero edge tree is also d p . The node d p is located on the path from v 0 to the first node, say v f , among the 0 r -children of v 0 (note that since the zero edge tree is an ordered tree, we can well-define the “first” node). That is, d p is an ancestor of v f . Since the position of v f is the next of the position of v 0 in M (in the preorder), we can obtain the position of v f by select 1 ( M , rank 1 ( M , v 0 ) + 1 ) . Noting that the index of d p is i 1 , we obtain the position of d p by d p = level _ ancestor ( U , select 1 ( M , rank 1 ( M , v 0 ) + 1 ) , i 1 ) . Our task is to find the node v such that one ( v ) = v 1 among the children of d p . Since the 0 r -children v of d p are sorted in the lexicographic order of index ( v ) , prank ( one ( v ) ) values by the construction algorithms, we can find v by a binary search. For this, we use the degree and child operations on the zero-edge tree (recall that degree is used for obtaining the number of children of a node).
If v does not exist, we create such a node and register it to the hash table as well as a dynamic ZDD. Note that we do not update the DenseZDD, and thus if we want to treat the ZDD, say Z new , whose root is the new node as the DenseZDD, we need to construct the DenseZDD structure for Z new .
We obtain the following theorem on the time complexity.
Theorem 3.
The existence of getnode ( i , v 0 , v 1 ) can be checked in O ( t log m ) time, where t is the time complexity of primitive ZDD operations.
If the BP sequence is not compressed, getnode takes O ( log m ) time; otherwise it takes O ( log 2 m ) time. By discussion similar to the proofs of Theorems 1 and 2 in Section 5, we have the following theorems.
Theorem 4.
A ZDD with m nodes on n items can be stored in 2 u + m log m + 3 m + o ( u ) bits so that the getnode ( i , v 0 , v 1 ) operation is done in O ( log m ) time, where u is the number of real and dummy nodes in the zero edge tree of D Z ( Z ) .
Theorem 5.
A ZDD with m nodes on n items can be stored in O ( m ( log m + log n ) ) bits so that the getnode ( i , v 0 , v 1 ) operation is done in O ( log 2 m ) time.

7. Other Decision Diagrams

7.1. Sets of Strings

A sequence binary decision diagram (SeqBDD) [17] is a variant of a zero-suppressed binary decision diagram, customized to manipulate sets of strings. The terminology of SeqBDDs is almost the same as that of ZDDs. Let c 1 , , c n be letters such that c 1 < c 2 < < c n and Σ n = { c 1 , , c n } be an alphabet. Let s = x 1 , , x l , l 0 , x 1 , , x Σ n , be a string. We denote the length of s by | s | = . The empty string is denoted by ε . The concatenation of strings s = x 1 , , x 1 and t = y 1 , , y 2 is defined as s · t = x 1 , , x 1 , y 1 , , y 2 . The product of string sets L 1 and L 2 is defined as L 1 × L 2 = { s 1 · s 2 | s 1 L 1 , s 2 L 2 } .
A SeqBDD is a directed acyclic graph. The difference between SeqBDD and ZDD is a restriction for indices of nodes connected by edges. For any SeqBDD nonterminal node v, the index of v’s 0-child must be smaller than that of v, but the index of v’s 1-child can be larger than or equal to that of v. This relaxation is required to represent string sets because a string can have the same letters at multiple positions. The definition of SeqBDDs is the following:
Definition 3 (string set represented by a SeqBDD).
A SeqBDD G = ( V , E ) rooted at a node v V represents a finite sets of strings L ( v ) whose letters are in Σ n defined recursively as follows: (1) If v is a terminal node: L ( v ) = { ε } if value ( v ) = 1 , and L ( v ) = if value ( v ) = 0 ; (2) If v is a nonterminal node, then L ( v ) is the finite set of strings L ( v ) = ( { { c index ( v ) } } × L ( one ( v ) ) ) L ( zero ( v ) ) .
A string s = x 1 , , x describes a path in the graph G starting from the root in the same way as ZDDs. For SeqBDDs, we also employ the zero-suppress rule and the sharing rule. By applying these rules as much as possible, we can obtain the canonical form for given sets of strings.
We can compress SeqBDDs by the same algorithm as the DenseZDD construction algorithm. We call it DenseSeqBDD. Since the index restriction between nodes connected by 0-edges is still valid on SeqBDDs, we can represent indices of nodes and connection by 0-edges among nodes by zero-edge trees. The main operations of SeqBDD such as index , zero , one , topset , member , count , and sample are also implemented by the same algorithms. Recall that a longest path on a ZDD is bounded by the number of items n. Therefore, the time complexities of member and sample on a ZDD are at most O ( n ) , which means that the benefit we can gain by skipping continuous 0-edges in topset algorithm is not so large because the total number of nodes we can skip is less than n. However, a longest path on a SeqBDD is not bounded by the number of letters, and thus we can gain more benefit of skipping 0-edges because indices of nodes reached after traversing 1-edges can be the largest index. The time complexities of member and sample on a SeqBDD are O ( maxlen ) and O ( maxlen log | Σ n | ) , respectively, where maxlen is the length of the longest string included in the SeqBDD.

7.2. Boolean Functions

In the above subsection, we applied our technique to decision diagrams for sets of strings. Next, we consider another decision diagram for Boolean functions, BDD. Is it possible to compress BDDs by the same technique, and are operations fast on such compressed BDDs? The answer to the first question is “Yes”, but to the second question is “No”. Since a BDD is also a directed acyclic graph consisting of two terminal nodes and nonterminal nodes with distinguishable two edges, the structure of a BDD can be represented by the zero-edge tree, dummy node vector, and one-child array. Therefore, we can obtain a compressed representation of a BDD. On the other hand, the membership operation on a ZDD corresponds to the operation to determine whether or not an assignment of Boolean variables satisfies the Boolean function represented by a BDD. Since the size of query for the assignment operation is always the number of all Boolean variables, we cannot skip any assignment to variables. As a result, membership operation and random sampling operation are not accelerated on a BDD even if we use the DenseZDD technique.

8. Experimental Results

We ran experiments to evaluate the compression, construction, and operation times of DenseZDDs. We implemented the algorithms described in Section 3 and Section 3.2 in C/C++ languages on top of the SAPPORO BDD package, which is available at https://github.com/takemaru/graphillion/tree/master/src/SAPPOROBDD and can be found as an internal library of Graphillion [18]. The package uses 32 bytes per ZDD node. The breakdown of 32 bytes of a ZDD node is as follows: 5 bytes as a pointer for the 1-child, 5 bytes as a pointer for the 0-child, 2 bytes as an index. In addition, we use a closed hash table to execute getnode operation. The size of the hash table of SAPPOROBDD is 5 × 2 × n bytes, and 5 bytes per each node to chain ZDD nodes that have the same key computed from its attribute-triple. Since DenseZDD does not require such hash table to execute getnode , we consider that the space used by the hash table should be included in the memory consumption of ZDD nodes. The experiments are performed on a machine with 3.70 GHz Intel Core i7-8700K and 64 GB memory running Windows Subsystem for Linux (Ubuntu) on Windows 10.
We show the characteristics of the data sets in Table 2. As artificial data sets, we use rectrxw, which represents families of sets i = 0 r 1 { { i w + 1 } , , { i w + w } } . Data set randomjoink is a ZDD that represents the join C 1 C 4 of four ZDDs for random families C 1 , , C 4 consisting of k sets of size one drawn from the set of n = 32768 items. Data set bddqueenk is a ZDD that stores all solutions for k-queen problem.
As real data sets, data set filename:p is a ZDD that is constructed from itemset data (http://fimi.ua.ac.be) by using the algorithm of all frequent itemset mining, named LCM over ZDD [3], with minimum support p.
The other ZDDs are constructed from Boolean functions data (https://ddd.fit.cvut.cz/prj/Benchmarks/). These data are commonly used to evaluate the size of ZDD-based data structures [2,19,20]. These ZDDs represent Boolean functions in a conjunctive normal form as families of sets of literals. For example, a function x 1 x 2 ¯ + x 2 ¯ x 3 + x 3 x 1 is translated into the family of sets { { x 1 , x 2 ¯ } , { x 2 ¯ , x 3 } , { x 3 , x 1 } } .
In Table 3, we show the sizes of the original ZDDs, the DenseZDDs, the dummy-compressed DenseZDDs and their compression ratios. The dummy node ratio, denoted by δ , of a DenseZDD is the ratio of the number of dummy nodes to that of both real nodes and dummy nodes in the DenseZDD. We compressed FID for the dummy node vector if the dummy node ratio is more than 75%. We observe that DenseZDDs are five to eight times smaller than original ZDDs, and dummy-compressed DenseZDDs are six to ten times smaller than original ZDDs. We also observe that dummy node ratios highly depend on data. They ranged from about 5% to 30%. For each data set, the higher the dummy node ratio was, the lower the compression ratio of the size of the DenseZDD to that of the ZDD became, and the higher the compression ratio of the size of the dummy-compressed DenseZDD to that of the DenseZDD became.
In Table 4, we show the conversion time from the ZDD to the DenseZDD and the getnode time on each structure for each data set. Conversion time is composed of three parts: converting a given ZDD to raw parentheses, bits, and integers, constructing the succinct representation of them, and compressing the BP of the zero-edge tree. The conversion time is almost linear in the input size. This result shows its scalability for large data. For each data set except for rectrxw, the getnode time on the DenseZDD is almost two times larger than that on the ZDD and that on the dummy-compressed DenseZDD is five to twenty times larger than that on the ZDD.
In Table 5, we show the traversal time and the search time. The traverse operation uses zero ( i ) and one ( i ) , while the membership operation uses topset ( i , c ) and one ( i ) . We observe that the DenseZDD requires about three or four times longer traversal time and about 3–1500 times shorter search time than the original ZDD for each data set except for Boolean functions. These results show the efficiency of our algorithm of the topset ( i , c ) operation on DenseZDD using level ancestor operations. The traversal times on dummy-compressed DenseZDDs are seven times slower and the search time on them are two times slower than DenseZDDs.
In Table 6, we show the counting time and the random sampling time. For each data set, the counting time on the DenseZDD and the random sampling time of the naive algorithm on both the DenseZDD and the dummy-compressed DenseZDD are not so far from those on the ZDD, while the counting time on the dummy-compressed DenseZDD is two to ten times larger than the ZDD. For each data set, the random sampling time of the binary search-based algorithm is two to hundred times smaller than the ZDD. For Boolean functions, the algorithm is three to six times slower. There is not much difference between DenseZDDs and dummy-compressed DenseZDDs.
From the above results, we conclude that DenseZDDs are more compact than ordinary ZDDs unless the dummy node ratio is extremely high, and the membership operations for DenseZDDs are much faster if n is large or the number of 0-edges from terminal nodes to each node is large. We observed that DenseZDD makes traversal time approximately triple, search time approximately one-tenth, and random sampling time approximately one-third compared to the original ZDDs.

9. Conclusions

In this paper, we have presented a compressed index for a static ZDD, named DenseZDD. We have also proposed a hybrid method for dynamic operations on DenseZDD such that we can manipulate a DenseZDD and a conventional ZDD together.

Author Contributions

Conceptualization, S.D., J.K., K.T., H.A., S.-i.M. and K.S.; Methodology, S.D. and K.S.; Software, S.D. and K.S.; Validation, S.D.; Formal Analysis, S.D., J.K., H.A., S.-i.M. and K.S.; Investigation, S.D. and K.S.; Resources, S.-i.M. and K.S.; Data Curation, S.D.; Writing—original Draft Preparation, S.D. and K.S.; Writing—review & Editing, S.D. and J.K.; Visualization, S.D. and J.K.; Supervision, S.D. and K.S.; Project Administration, S.D., S.-i.M. and K.S.; Funding Acquisition, S.D., K.T., S.-i.M. and K.S.

Funding

This work was supported by Grant-in-Aid for JSPS Fellows 25193700. This work was supported by JSPS Early-Career Scientists Grand Number 18K18102. This research was partly supported by Grant-in-Aid for Scientific Research on Innovative Areas—Exploring the Limits of Computation, MEXT, Japan and ERATO MINATO Discrete Structure Manipulation System Project, JST, Japan. K.T. is supported by JST CREST and JSPS Kakenhi 25106005. K.S. is supported by JSPS KAKENHI 23240002.

Acknowledgments

The first author would like to thank Yasuo Tabei, Roberto Grossi, and Rajeev Raman for their discussions and valuable comments. We also would like to thank the anonymous reviewers for their helpful comments.

Conflicts of Interest

The authors declare no conflict of interest.

References

  1. Bryant, R.E. Graph-Based Algorithms for Boolean Function Manipulation. IEEE Trans. Comput. 1986, 100, 677–691. [Google Scholar] [CrossRef]
  2. Minato, S. Zero-Suppressed BDDs for Set Manipulation in Combinatorial Problems. In Proceedings of the Thirtieth AAAI Conference on Artificial Intelligence, Phoenix, AZ, USA, 12–17 February 2016; pp. 1058–1066. [Google Scholar]
  3. Minato, S.; Uno, T.; Arimura, H. LCM over ZBDDs: Fast Generation of Very Large-Scale Frequent Itemsets Using a Compact Graph-Based Representation. In Proceedings of the Advances in Knowledge Discovery and Data Mining (PAKDD), Osaka, Japan, 20–23 May 2008; pp. 234–246. [Google Scholar]
  4. Minato, S.; Arimura, H. Frequent Pattern Mining and Knowledge Indexing Based on Zero-Suppressed BDDs. In Proceedings of the 5th International Workshop on Knowledge Discovery in Inductive Databases (KDID 2006), Berlin, Germany, 18 September 2006; pp. 152–169. [Google Scholar]
  5. Knuth, D.E. The Art of Computer Programming, Fascicle 1, Bitwise Tricks & Techniques; Binary Decision Diagrams; Addison-Wesley: Boston, MA, USA, 2009; Volume 4. [Google Scholar]
  6. Minato, S. SAPPORO BDD Package; Division of Computer Science, Hokkaido University: Sapporo, Japan, 2012; unreleased. [Google Scholar]
  7. Denzumi, S.; Kawahara, J.; Tsuda, K.; Arimura, H.; Minato, S.; Sadakane, K. DenseZDD: A Compact and Fast Index for Families of Sets. In Proceedings of the International Symposium on Experimental Algorithms 2014, Copenhagen, Denmark, 29 June–1 July 2014. [Google Scholar]
  8. Raman, R.; Raman, V.; Satti, S.R. Succinct indexable dictionaries with applications to encoding k-ary trees, prefix sums and multisets. ACM Trans. Algorithms 2007, 3, 43. [Google Scholar] [CrossRef]
  9. Navarro, G.; Sadakane, K. Fully-Functional Static and Dynamic Succinct Trees. ACM Trans. Algorithms 2014, 10, 16. [Google Scholar] [CrossRef]
  10. Minato, S.; Ishiura, N.; Yajima, S. Shared Binary Decision Diagram with Attributed Edges for Efficient Boolean function Manipulation. In Proceedings of the 27th ACM/IEEE Design Automation Conference, Orlando, FL, USA, 24–28 June 1990; pp. 52–57. [Google Scholar]
  11. Denzumi, S.; Yoshinaka, R.; Arimura, H.; Minato, S. Sequence binary decision diagram: Minimization, relationship to acyclic automata, and complexities of Boolean set operations. Discret. Appl. Math. 2016, 212, 61–80. [Google Scholar] [CrossRef]
  12. Minato, S. Z-Skip-Links for Fast Traversal of ZDDs Representing Large-Scale Sparse Datasets. In Proceedings of the European Symposium on Algorithms, Sophia Antipolis, France, 2–4 September 2013; pp. 731–742. [Google Scholar]
  13. Maruyama, S.; Nakahara, M.; Kishiue, N.; Sakamoto, H. ESP-index: A compressed index based on edit-sensitive parsing. J. Discret. Algorithms 2013, 18, 100–112. [Google Scholar] [CrossRef] [Green Version]
  14. Navarro, G. Compact Data Structures; Cambridge University Press: Cambridge, UK, 2016. [Google Scholar]
  15. Elias, P. Universal codeword sets and representation of the integers. IEEE Trans. Inf. Theory 1975, 21, 194–203. [Google Scholar] [CrossRef]
  16. Okanohara, D.; Sadakane, K. Practical Entropy-Compressed Rank/Select Dictionary. In Proceedings of the Workshop on Algorithm Engineering and Experiments (ALENEX), New Orleans, LA, USA, 6 January 2007. [Google Scholar]
  17. Loekito, E.; Bailey, J.; Pei, J. A binary decision diagram based approach for mining frequent subsequences. Knowl. Inf. Syst. 2010, 24, 235–268. [Google Scholar] [CrossRef]
  18. Inoue, T.; Iwashita, H.; Kawahara, J.; Minato, S. Graphillion: Software library for very large sets of labeled graphs. Int. J. Softw. Tools Technol. Transf. 2016, 18, 57–66. [Google Scholar] [CrossRef]
  19. Bryant, R.E. Chain Reduction for Binary and Zero-Suppressed Decision Diagrams. In Proceedings of the Tools and Algorithms for the Construction and Analysis of Systems, Thessaloniki, Greece, 14–21 April 2018; pp. 81–98. [Google Scholar]
  20. Nishino, M.; Yasuda, N.; Minato, S.; Nagata, M. Zero-suppressed Sentential Decision Diagrams. In Proceedings of the Thirtieth AAAI Conference on Artificial Intelligence, Phoenix, AZ, USA, 12–17 February 2016; pp. 272–277. [Google Scholar]
Figure 1. Example of ZDD.
Figure 1. Example of ZDD.
Algorithms 11 00128 g001
Figure 2. Reduction rules of ZDDs.
Figure 2. Reduction rules of ZDDs.
Algorithms 11 00128 g002
Figure 3. ZDD using 0-element edges that is equivalent to the ZDD in Figure 1.
Figure 3. ZDD using 0-element edges that is equivalent to the ZDD in Figure 1.
Algorithms 11 00128 g003
Figure 4. Worst-case example of a straightforward translation.
Figure 4. Worst-case example of a straightforward translation.
Algorithms 11 00128 g004
Figure 5. Example of the construction of the zero-edge tree from a ZDD by inserting dummy nodes and adding/deleting edges. A black and white circle represents a dummy and real node, respectively. The number in a circle represents its index. A dotted arrow in the left figure represents a 0-edge.
Figure 5. Example of the construction of the zero-edge tree from a ZDD by inserting dummy nodes and adding/deleting edges. A black and white circle represents a dummy and real node, respectively. The number in a circle represents its index. A dotted arrow in the left figure represents a 0-edge.
Algorithms 11 00128 g005
Figure 6. Zero-edge tree and a dummy node vector obtained from the ZDD in Figure 3.
Figure 6. Zero-edge tree and a dummy node vector obtained from the ZDD in Figure 3.
Algorithms 11 00128 g006
Figure 7. One-child array obtained from the ZDD in Figure 3.
Figure 7. One-child array obtained from the ZDD in Figure 3.
Algorithms 11 00128 g007
Figure 8. Computing real preorder ranks from the 0-terminal node to real nodes with higher indices.
Figure 8. Computing real preorder ranks from the 0-terminal node to real nodes with higher indices.
Algorithms 11 00128 g008
Table 1. Main operations supported by ZDD. The first group are the primitive ZDD operations used to implement the others, yet they could have other uses.
Table 1. Main operations supported by ZDD. The first group are the primitive ZDD operations used to implement the others, yet they could have other uses.
index ( v ) Returns the index of node v.
zero ( v ) Returns the 0-child of node v.
one ( v ) Returns the 1-child of node v.
getnode ( i , v 0 , v 1 ) Generates (or makes a reference to) a node v
with index i and two child nodes v 0 = zero ( v ) and v 1 = one ( v ) .
topset ( v , i ) Returns a node with the index i reached by traversing only 0-edges from v.
If such a node does not exist, it returns the 0-terminal node.
member ( v , S ) Returns true if S F ( v ) , and returns false otherwise.
count ( v ) Returns | F ( v ) | .
sample ( v ) Returns a set S F ( v ) uniformly and randomly.
offset ( v , i ) Returns u such that F ( u ) = { S U n | S F , e i S } .
onset ( v , i ) Returns u such that F ( u ) = { S \ { e i } U n | S F , e i S } .
apply ( v 1 , v 2 ) Returns v such that F ( v ) = F ( v 1 ) F ( v 2 ) , for { , , \ , } .
Table 2. Detail of data sets and their ZDD size.
Table 2. Detail of data sets and their ZDD size.
Data Setn | F | F #roots#nodes
rect1x1000010,00010,00010,000110,001
rect5x200010,000 3.2 × 10 16 1.6 × 10 17 110,001
rect100x10010,000 1.0 × 10 200 1.0 × 10 202 110,001
rect2000x510,000 8.7 × 10 1397 1.7 × 10 1401 110,001
rect10000x110,000110,000110,001
randomjoin25632,740 4.3 × 10 9 1.7 × 10 10 125,743
randomjoin204832,765 1.7 × 10 13 7.0 × 10 13 1375,959
randomjoin819232,768 3.6 × 10 15 1.4 × 10 16 1 1.3 × 10 6
randomjoin1638432,768 2.8 × 10 16 1.1 × 10 17 1 1.9 × 10 6
bddqueen1316973,712958,2561204,782
bddqueen14196365,596 5.1 × 10 6 1911,421
bddqueen15225 2.3 × 10 6 3.4 × 10 7 1 4.8 × 10 6
T40I10D100K:0.001925 7.0 × 10 7 8.2 × 10 8 1 1.1 × 10 6
T40I10D100K:0.0005933 2.0 × 10 8 2.1 × 10 9 1 6.5 × 10 6
T40I10D100K:0.0001942 1.2 × 10 10 1.5 × 10 11 1 1.9 × 10 8
accidents:0.176 1.1 × 10 7 1.1 × 10 8 136,324
accidents:0.05106 8.3 × 10 7 9.3 × 10 8 1183,144
accidents:0.01167 4.1 × 10 9 5.3 × 10 10 1 4.7 × 10 6
chess:0.162 4.6 × 10 9 6.4 × 10 10 1 1.1 × 10 6
chess:0.0567 4.1 × 10 10 6.2 × 10 11 1 3.1 × 10 6
chess:0.0172 1.6 × 10 12 2.9 × 10 13 1 5.8 × 10 6
connect:0.0587 4.1 × 10 11 6.9 × 10 12 1331,829
connect:0.01110 1.7 × 10 13 3.2 × 10 14 1 2.3 × 10 6
connect:0.005116 6.8 × 10 13 1.3 × 10 15 1 4.1 × 10 6
16-adder_col66 9.7 × 10 6 2.7 × 10 8 17 1.5 × 10 6
C190866 3.7 × 10 8 1.1 × 10 10 25133,379
C3540100 5.0 × 10 6 1.3 × 10 8 22 1.5 × 10 6
C49982 4.9 × 10 11 1.9 × 10 13 32140,932
C880120 2.4 × 10 6 7.0 × 10 7 26606,310
comp64196,606 6.0 × 10 6 3589,783
my_adder66655,287 2.0 × 10 7 17884,662
Table 3. Comparison of performance, where δ denotes the dummy node ratio. Z, D Z , and D Z d c indicate ordinary ZDDs, DenseZDDs and dummy-compressed DenseZDDs, respectively.
Table 3. Comparison of performance, where δ denotes the dummy node ratio. Z, D Z , and D Z d c indicate ordinary ZDDs, DenseZDDs and dummy-compressed DenseZDDs, respectively.
Data SetSize (byte)Comp. Ratio δ
ZDZDZ dc DZDZ dc
rect1x10000320,03214,66210,3720.0000.0460.032
rect5x2000320,03236,94729,2270.4440.1150.091
rect100x100320,03238,01429,6480.4980.1190.093
rect2000x5320,03238,07832,1000.5000.1190.100
rect10000x1320,03238,07834,0480.5000.1190.106
randomjoin256823,760792,703279,7190.9780.9620.340
randomjoin2048 1.2 × 10 7 2.5 × 10 6 1.6 × 10 6 0.8210.2100.135
randomjoin8192 4.0 × 10 7 5.6 × 10 6 4.7 × 10 6 0.4240.1390.115
randomjoin16384 6.0 × 10 7 7.7 × 10 6 6.8 × 10 6 0.1450.1280.113
bddqueen13 6.1 × 10 6 846,809752,7750.4660.1380.123
bddqueen14 2.7 × 10 7 4.2 × 10 6 3.7 × 10 6 0.5100.1530.136
bddqueen15 1.4 × 10 8 2.5 × 10 7 2.2 × 10 7 0.5580.1710.151
T40I10D100K:0.001 3.6 × 10 7 8.0 × 10 6 5.3 × 10 6 0.8260.2200.148
T40I10D100K:0.0005 2.1 × 10 8 4.0 × 10 7 3.0 × 10 7 0.7480.1910.141
T40I10D100K:0.0001 6.0 × 10 9 1.2 × 10 9 9.4 × 10 8 0.7030.2000.159
accidents:0.1 1.2 × 10 6 125,440117,7140.0830.1080.101
accidents:0.05 5.9 × 10 6 672,553634,1690.0790.1150.108
accidents:0.01 1.5 × 10 8 2.0 × 10 7 1.9 × 10 7 0.0890.1350.128
chess:0.1 3.7 × 10 7 4.6 × 10 6 4.4 × 10 6 0.0980.1270.120
chess:0.05 1.0 × 10 8 1.3 × 10 7 1.2 × 10 7 0.0980.1310.124
chess:0.01 1.8 × 10 8 2.5 × 10 7 2.3 × 10 7 0.1180.1350.127
connect:0.05 1.1 × 10 7 1.3 × 10 6 1.2 × 10 6 0.2060.1220.112
connect:0.01 7.3 × 10 7 9.7 × 10 6 9.0 × 10 6 0.2040.1330.124
connect:0.005 1.3 × 10 8 1.8 × 10 7 1.6 × 10 7 0.2020.1330.124
16-adder_col 4.9 × 10 7 6.2 × 10 6 5.9 × 10 6 0.1240.1270.122
C1908 4.3 × 10 6 487,434470,4220.0270.1140.110
C3540 4.6 × 10 7 5.9 × 10 6 5.6 × 10 6 0.1520.1280.122
C499 4.5 × 10 6 513,322499,1580.0090.1140.111
C880 1.9 × 10 7 2.5 × 10 6 2.3 × 10 6 0.3050.1290.120
comp 1.9 × 10 7 2.4 × 10 6 2.2 × 10 6 0.2340.1270.119
my_adder 2.8 × 10 7 3.8 × 10 6 3.5 × 10 6 0.3990.1330.122
Table 4. Converting time and getnode time.
Table 4. Converting time and getnode time.
Data SetConversion Time (s)Getnode Time (s)
convertconst.comp.ZDZDZ dc
rect1x100000.0070.0090.0080.0010.0010.005
rect5x20000.0060.0150.0110.0000.0010.006
rect100x1000.0060.0140.0090.0010.0010.005
rect2000x50.0060.0160.0120.0000.0010.005
rect10000x10.5040.0150.0090.0000.0010.008
randomjoin2560.0250.1050.0050.0010.0020.013
randomjoin20480.2540.2630.0010.0360.0370.189
randomjoin81920.9460.5260.0000.1560.1640.710
randomjoin163841.4630.6920.0100.2350.2781.123
bddqueen130.1750.0870.0030.0090.0170.159
bddqueen140.9260.4150.0190.0590.0740.692
bddqueen156.2172.4380.1420.4260.4023.498
T40I10D100K:0.0010.9340.8140.0370.0890.2180.872
T40I10D100K:0.00056.0063.9580.1750.7711.0884.706
T40I10D100K:0.0001233.006120.4234.37832.31630.181122.104
accidents:0.10.0260.0400.0230.0020.0050.033
accidents:0.050.1620.0940.0220.0120.0230.161
accidents:0.015.9011.9490.0750.7850.6574.568
chess:0.11.1490.4550.0160.1420.1451.130
chess:0.053.3191.2630.0850.4710.4142.895
chess:0.015.8292.4080.0980.8470.7294.662
connect:0.050.2890.1360.0020.0230.0370.227
connect:0.012.2870.9450.0330.2970.2681.625
connect:0.0054.3771.7160.0800.5790.4912.996
16-adder_col1.3180.5850.0100.1190.1371.821
C19080.0850.0700.0160.0060.0110.147
C35401.3190.5630.0170.0980.1191.488
C4990.0840.0730.0100.0070.0100.140
C8800.4910.2490.0050.0340.0480.551
comp0.4450.2320.0020.0320.0460.683
my_adder0.7430.3750.0090.0610.0830.930
Table 5. DFS traversal time and random searching time.
Table 5. DFS traversal time and random searching time.
Data SetTraverse Time (s)Search Time (s)
ZDZDZ dc ZDZDZ dc
rect1x100000.0000.0020.0024.5630.0120.014
rect5x20000.0000.0020.0022.0820.0140.015
rect100x1000.0000.0010.0020.0920.0090.011
rect2000x50.0010.0020.0030.0060.0090.021
rect10000x10.0010.0030.0150.0020.0090.070
randomjoin2560.0010.0040.0050.4700.0130.013
randomjoin20480.0210.0570.0653.7720.0140.015
randomjoin81920.0880.1760.20114.5680.0190.020
randomjoin163840.1440.2690.30625.2440.0160.016
bddqueen130.0130.0540.2370.0140.0050.007
bddqueen140.0680.2590.9980.0150.0050.006
bddqueen150.4201.4214.7780.0160.0050.006
T40I10D100K:0.0010.0540.2220.2980.0030.0020.003
T40I10D100K:0.00050.3141.2101.6060.0030.0020.002
T40I10D100K:0.000111.61542.73055.0850.0040.0010.002
accidents:0.10.0020.0070.0280.0030.0000.000
accidents:0.050.0110.0380.1500.0030.0000.000
accidents:0.010.3691.1654.5070.0030.0000.000
chess:0.10.0750.2511.0000.0030.0000.000
chess:0.050.2180.7072.6400.0030.0000.000
chess:0.010.3941.2763.9110.0030.0000.000
connect:0.050.0220.0690.1690.0030.0000.000
connect:0.010.1690.4921.2190.0030.0000.000
connect:0.0050.3160.9062.2500.0030.0000.000
16-adder_col0.0900.3402.0540.0530.0020.018
C19080.0070.0300.1740.1690.2211.851
C35400.0850.3582.1620.0720.1231.017
C4990.0070.0310.1710.1010.1450.988
C8800.0330.1470.8150.0810.1591.331
comp0.0350.1380.9560.0100.0100.085
my_adder0.0660.1850.9310.0540.0010.003
Table 6. Counting time and random sampling time.
Table 6. Counting time and random sampling time.
Data SetCount Time (sec)Sample Time (sec)
DDZDZ dc ZDZ (naive)DZ (bin)DZ dc (naive)DZ dc (bin)
rect1x100000.0020.0020.0035.3754.8130.0145.5270.014
rect5x20000.0010.0020.0039.1255.1260.0634.8250.062
rect100x1000.0020.0030.00310.1505.1550.8165.1760.812
rect2000x50.0040.0050.0078.2505.7657.1425.7737.171
rect10000x10.0010.0040.0160.0010.0110.0120.0740.075
randomjoin2560.0030.0070.0071.0350.5350.0360.5640.035
randomjoin20480.0670.0910.1027.6504.2540.0484.0560.048
randomjoin81920.2560.3050.33622.98916.8300.05615.6630.056
randomjoin163840.3930.4550.50831.56124.0360.05823.3570.059
bddqueen130.0290.0770.2650.0370.0260.0260.0260.026
bddqueen140.1490.3801.1460.0420.0290.0310.0300.031
bddqueen150.8762.2265.6640.0470.0330.0350.0340.035
T40I10D100K:0.0010.1870.3390.4180.9470.3380.0470.3230.045
T40I10D100K:0.00051.1531.9252.3380.9540.4790.0490.4950.047
T40I10D100K:0.000136.32967.11379.4350.9780.5760.0610.5720.066
accidents:0.10.0060.0110.0330.0770.0770.0360.0750.033
accidents:0.050.0310.0590.1750.1080.1060.0400.1050.040
accidents:0.010.9572.0665.4740.1690.1650.0500.1640.048
chess:0.10.2080.4131.1810.0620.0610.0500.0610.050
chess:0.050.5911.1883.1580.0670.0650.0560.0660.057
chess:0.011.0612.1154.8170.0730.0670.0730.0680.071
connect:0.050.0590.1080.2120.0880.0850.0660.0840.064
connect:0.010.4350.8281.5750.1110.1050.0760.1050.075
connect:0.0050.8041.5572.9250.1180.1090.0780.1110.077
16-adder_col0.2240.5052.2600.1670.2460.4740.2460.483
C19080.0160.0450.1910.2590.6581.3860.6621.398
C35400.1990.5302.3860.1500.3490.7150.3520.727
C4990.0170.0450.1890.4551.2412.5001.2502.529
C8800.0790.2140.9040.0840.2330.4800.2380.485
comp0.0810.1991.0380.0350.0550.1090.0550.109
my_adder0.1350.2781.0430.0810.2320.4160.2340.424

Share and Cite

MDPI and ACS Style

Denzumi, S.; Kawahara, J.; Tsuda, K.; Arimura, H.; Minato, S.-i.; Sadakane, K. DenseZDD: A Compact and Fast Index for Families of Sets . Algorithms 2018, 11, 128. https://doi.org/10.3390/a11080128

AMA Style

Denzumi S, Kawahara J, Tsuda K, Arimura H, Minato S-i, Sadakane K. DenseZDD: A Compact and Fast Index for Families of Sets . Algorithms. 2018; 11(8):128. https://doi.org/10.3390/a11080128

Chicago/Turabian Style

Denzumi, Shuhei, Jun Kawahara, Koji Tsuda, Hiroki Arimura, Shin-ichi Minato, and Kunihiko Sadakane. 2018. "DenseZDD: A Compact and Fast Index for Families of Sets " Algorithms 11, no. 8: 128. https://doi.org/10.3390/a11080128

APA Style

Denzumi, S., Kawahara, J., Tsuda, K., Arimura, H., Minato, S. -i., & Sadakane, K. (2018). DenseZDD: A Compact and Fast Index for Families of Sets . Algorithms, 11(8), 128. https://doi.org/10.3390/a11080128

Note that from the first issue of 2016, this journal uses article numbers instead of page numbers. See further details here.

Article Metrics

Back to TopTop