Inf 3015 - Graph
Inf 3015 - Graph
Abstract
1 Generalities
Let n be the information-theoretic optimal number of bits needed to store data. A
representation of this data is called:
This document focus on succinct data structures. The goal of succinct data structure
is to use an amount of space "close" to the information-theoretic lower bound and, in
comparison to classical compressed representation, still allow efficient query operations.
Succinct data structure have two principal operations called rank and select. Near to
these two operations we also have successor and predecessor operations.
S 1 0 0 1 0 1 0 0 1 1 1 0 0 1 0 0 1 1 0 1 0 0 1 0
1
1.1 Rank operation
rankb (S, k) function counts the number of elements b (most often bits) in the prefix of
an array S up to some index k. In other words, this function tells us the number of "b"
we have from the first position to k th position. Mathematically, this function is expressed
as follow:
rankb (S, k) = |{i, i ∈ [1, k] and S[i] = b}|.
• select1 (S, 14) = −1, select0 (S, 14) = −1, -1 means that there no such position.
2
Example: With the same vector S in table 1, we have:
• succ7 (S, 1) = select1 (S, rank1 (S, 7) + 1) = select1 (S, 3 + 1) = select1 (S, 4) = 9
• succ4 (S, 0) = select0 (S, rank0 (S, 4) + 1) = select0 (S, 2 + 1) = select0 (S, 3) = 5
• succ7 (S, 0) = select0 (S, rank0 (S, 7) + 1) = select0 (S, 4 + 1) = select0 (S, 5) = 8
• pred4 (S, 1) = select1 (S, rank1 (S, 4) − 1) = select1 (S, 2 − 1) = select1 (S, 1) = 1
• pred7 (S, 1) = select1 (S, rank1 (S, 7) − 1) = select1 (S, 3 − 1) = select1 (S, 2) = 4
• pred4 (S, 0) = select0 (S, rank0 (S, 4) − 1) = select0 (S, 2 − 1) = select0 (S, 1) = 2
• pred7 (S, 0) = select0 (S, rank0 (S, 7) − 1) = select0 (S, 4 − 1) = select0 (S, 3) = 5
2 LOUDS Formalization
In this section, we described LOUDS encoding as it is described in [1]. LOUDS stands for
Level-Order Unary Degree Sequence. LOUDS encoding consists in turning a tree into an
array of bits via a breadth first search. The resulting array is the ordered concatenation
of the bit representation of each node.
Each node is represented by a list of bits that contains as many as 1-bits as there are
children and that is terminated by a 0-bit. Figure 1 shows an example of tree with its
LOUDS encoding. For example node 1 (the root) is represented in LOUDS encoding by
1110. This is because it has three children. There is a node before the root represented
by 10.
3
Figure 1: Example of tree with its LOUDS encoding
4
Algorithm 1 : Tree BFS (Breadth First Search)
Input: T ree T
Output:
1: File f;
2: f.enqueue(T.root);
3: while f.empty()<>true do
4: t ← f.dequeue()
5: treat(t);
6: treated.add(t);
7: children ← t.children()
8: for all child ∈ children do
9: if child ∈
/ treated then
10: f.enqueue(child);
11: end if
12: end for
13: end while
1. parent(4) =?
So, parent(4) = 1.
2. parent(9) =?
So, parent(9) = 4.
5
Algorithm 2 : LOUDS encoding
Input: 5 − ary − T ree T
Output: LOUDS encoding CODE[N], N is the number of nodes of T.
• Iterate over the position x + 1, x + 2, ..., as long as the corresponding bit is ’1’.
For each such position x + k with B[x + k] = 1, the level-order numbers of i’s children
are rank1 (B, x + k), which can be simplified to x − i + k.
1. children(4) =?
2. children(8) =?
6
(a) x = select0 (B, 8) = 17
(b) chil = {rank1 (B, x+k), 1 ≤ k ≤ t where t is the f irst integer such that B[x+
t] = 0} = {rank1 (B, 17 + 1)} = {17 − 8 + 1} = {10}
3 GLOUDS Formalization
In this section we present GLOUDS formalization as it was described at [3]. Graph 2 will
be used as example.
As in [3], we assume that the graph is directed. The following characteristics are
considered:
• c ≤ n is the number of roots in G (the number of nodes that form the set from
which we can reach every node of G)
• h ≤ k is the number of nodes with more than 1 incoming edge (non-tree nodes).
7
root does not exists, and there are many roots in the graph, one can still run algorithm
3 for each root and finally build a super-root that will be the parent of all these roots.
Algorithm 3 starts by putting the root in a file data structure at line 2. At line 3,
we put the root in the marked nodes list. While the file is not empty, one node is taken
from the file (line 6), then their non-marked neighbors are put in the file (line 9), and
finally we treat it (line 13). Suppose that the treatment is printing. Then, BFS algorithm
applied to the graph of figure 2 is: 1 2 3 4 5 6 7 8.
Let TGBF S be the resulting BFS-tree after running algorithm 2. TGBF S is augmented
as follows:
• For each node w that is inspected but not visited during the BFS at node v (w has
already been visited at an earlier point), we make a copy of w and append it as a
child of v in the BFS-tree TGBF S . These nodes are called shadow nodes.
• We add a super-root to the initial root and call the resulting tree TG . This tree has
exactly m + 2 nodes. See the resulted tree of graph G at figure 3.
8
Figure 3: Resulting tree and shadow nodes of Graph G
• For the super root (line 2), we put "10" in the sequence (line 3)
– If this child is a real node, then put "1" in the sequence (line 11)
– If this child is shadow node, then put "2" in the sequence (line 14) and add
this node to the list of non-tree nodes H (line 15).
9
Algorithm 4 : GLOUDS encoding
Input: Graph G
Output: GLOUDS encoding B ∈ {0, 1, 2}∗ and H, the list of shadow nodes.
1: File f;
2: f.enqueue(G.root);
3: B.add("10"); //For the super root
4: marked_nodes.add(G.root);
5: while f.empty()<>true do
6: g ← f.dequeue()
7: neighbors ← g.neighbors()
8: for all node ∈ neighbors do
9: if node ∈
/ marked_nodes then
10: f.enqueue(node);
11: B.add("1"); //One child found
12: marked_nodes.add(node);
13: else
14: B.add("2"); //Another child found, but it is a child of another node.
16: end if
17: end for
18: B.add("0"); //Mark the end of children
19: treat(g);
20: treated_nodes.add(g);
21: end while
• If B[x] = 1, then the node is a real node, reaching it require the operation rank1 (B, x).
It is the xth 1 of B vector.
• If B[x] = 2, then the node is a shadow node, reaching it require the operation
H[rank2 (B, x) − 1] (line 6). We first find the xth 2 of B vector. Since it is a shadow
node, this position is used in H vector to identify the child.
Example: Consider B and H vectors in Figure 4. What are children(3) and children(4)?
1. children(4) =?
10
Figure 4: Resulting B and H vectors
Algorithm 5 : Children(i)
Input: integer i, GLOU DS_encode B
Output: List of children of node i.
1: x ← select0 (B, i) + 1;
2: while (B[x] 6= 0) do
3: if (B[x] = 1) then
4: Output(rank1 (B, x)); //This is a real node.
5: else
6: Output(H[rank2 (B, x) − 1]); //This is a shadow node.
7: end if
8: x ← x + 1;
9: end while
2. children(3) =?
11
(d)
(e) output(rank1 (B, x)) = output(rank1 (B, 9)) = output(5).
• Give the position p of the ith 1 (its gives node i at line 1).
• Count the number of 0 before p (its gives the first parent at line 2).
After printing the first parent, Algorithm 6 gives the other parents (now shadow
nodes) as follows:
• Look for the parent of p (counting the number of 0 from 1 to p). And then print it
(Line 7).
12
Algorithm 6 : Parents(i)
Input: integer i, GLOU DS_encode B
Output: List of parents of node i.
2: output rank0 (B, p); // Print the first parent which is the only tree node
3: x←j
4: x ← selecti (H, j); // Look for the position of the first occurrence of i in H
5: while (x < k) do
6: p ← select2 (B, x); // p is the position of the xth occurrence of 2 in B
7: output rank0 (B, p); // Print a parent which is shadow node (the number of 0 from 1 to p
8: j ←j+1
9: x ← selecti (H, j); // x is the position of the j th occurrence of i in H
4 Log(graph) Formalization
In this section we present Log(graph) formalization as it was described at [2].
5 Adopted Formalization
References
[1] Reynald Affeldt, Jacques Garrigue, Xuanrui Qi, and Kazunari Tanaka. Proving tree
algorithms for succinct data structures. arXiv preprint arXiv:1904.02809, 2019.
[2] Maciej Besta, Dimitri Stanojevic, Tijana Zivic, Jagpreet Singh, Maurice Hoerold, and
Torsten Hoefler. Log (graph) a near-optimal high-performance graph representation.
In Proceedings of the 27th International Conference on Parallel Architectures and
Compilation Techniques, pages 1–13, 2018.
13
[3] Johannes Fischer and Daniel Peters. Glouds: Representing tree-like graphs. Journal
of Discrete Algorithms, 36:39–49, 2016.
14