I/O-Efficient Algorithms for Planar Graphs I: Separators∗ Anil Maheshwari†
Norbert Zeh†
School of Computer Science Carleton University Ottawa, ON K1S 5B6 Canada
Faculty of Computer Science Dalhousie University Halifax, NS B3H 1W5 Canada
[email protected]
[email protected]
Abstract We present I/O-efficient algorithms for computing optimal separator partitions of planar graphs. Our main result shows that, given √ a planar graph G with N vertices and an integer r > 0, a vertex separator of size O (N/ r) that partitions G into O(N/r) subgraphs of size at most r √ and boundary size O ( r) can be computed in O(sort(N )) I/Os, provided that M ≥ 56r log2 B. Together with the planar embedding algorithm presented in the companion paper [27], this result is the basis for I/O-efficient solutions to many other fundamental problems on planar graphs, including breadth-first search and shortest paths [5, 8], depth-first search [6, 9], strong connectivity [9], and topological sorting [8]. Our second result shows that, given I/O-efficient solutions to these problems, a general separator algorithm for graphs with costs and weights on their vertices [3] can be made I/O-efficient. Many classical separator theorems are special cases of this result. In particular, our I/O-efficient version allows the computation of a separator as produced by our first separator algorithm, but without placing any constraints on r.
1
Introduction
I/O-efficient graph algorithms have received considerable attention because massive graphs arise naturally in many applications. Recent web crawls, for example, produce graphs of on the order of 200 million nodes and 2 billion edges. Recent work in web modelling uses depth-first search, breadth-first search, shortest paths, and connected components as primitive operations for investigating the structure of the web [12]. Massive graphs are also often manipulated in geographic information systems (GIS), where many fundamental problems can be formulated as basic graph problems. Yet another example of a massive graph is AT&T’s phone-call graph [13]. When working with such large data sets, the transfer of data between internal and external memory, and not the internal-memory computation, is often the bottleneck. Thus, I/O-efficient algorithms can lead to considerable run-time improvements. ∗
An extended abstract of this paper appeared in the Proceedings of the 13th ACM-SIAM Symposium on Discrete Algorithms, San Francisco 2002. † Research supported by NSERC and NCE GEOIDE.
1
Planar graphs are a natural abstraction of many real-world problems. For example, the graphs arising in GIS are often planar or “almost planar”. On the theoretical side, planar graphs are among the fundamental combinatorial structures used in algorithmic graph theory. Planar separators have played the key role in designing divide-and-conquer algorithms for planar graphs. The classical separator theorem for planar graphs by Lipton and Tarjan [26], coupled with linear-time embedding algorithms [10, 18, 23, 25], has led to phenomenal developments in algorithmic graph theory. Numerous research results that followed describe efficient algorithms for computing a variety of separators of other sparse graphs and discuss applications of separators such as lower bounds on the size of Boolean circuits, approximation algorithms for NP-complete problems, nested dissection of sparse systems of linear equations, load balancing in parallel numerical simulations based on the finite elements method, partitioning triangular irregular networks in the field of GIS, and encoding graphs. In external memory, planar separators have been the key to obtaining I/O-efficient algorithms for a variety of problems on embedded planar graphs, including breadth-first search (BFS) and single-source shortest paths [5, 8], depth-first search (DFS) [6, 9], strong connectivity [9], and topological sorting [8]. Existing internal-memory algorithms for computing planar separators (e.g., [2, 3, 26]) are not I/O-efficient because they all use BFS to gather structural information about the graph, and BFS and DFS are among those fundamental graph problems for which truly I/O-efficient solutions on general graphs are still lacking. The existing I/O-efficient BFS-algorithms for planar graphs [5, 8] are separator-based; hence, using them in a separator algorithm creates a circular dependency. In this paper, we present a new algorithm that applies BFS only to a compressed version of the given graph and combines this with graph contraction techniques to obtain an optimal separator partition in an I/O-efficient manner. An added benefit of our algorithm is that it does not require a planar embedding of the given graph.
1.1
Model of Computation and Previous Work
The algorithms in this paper are designed an analyzed in the I/O-model of Aggarwal and Vitter [1]. This model quite accurately captures the characteristics of current hard drives and yet is simple enough to allow the I/O-complexity of complex algorithms to be analyzed. In the I/O-model, the internal memory of the computer is capable of holding M data items, the disk is partitioned into blocks of B consecutive data items, and every disk access transfers one block of data between internal memory and disk. A disk access is referred to as an I/O-operation or I/O. The complexity of an algorithm is the number of I/O-operations it performs. For a survey of results obtained in the I/O-model and its extensions refer to [28, 32]. The following results are relevant to the work presented in this paper. It is shown in [1] that sorting and permuting an array of N data items take sort(N ) = Θ((N/B) log M/B (N/B)) and perm(N ) = Θ(min{N, sort(N )}) I/Os, respectively; scanning the array takes scan(N ) = Θ(N/B) I/Os. In internal memory, that is, in the RAM model, the problem of computing planar separators is well-studied. Lipton and Tarjan graph with N vertices √ [26] √ planar were the first to show that every has a 23 -separator of size O N , that is, a vertex set of size O N whose removal partitions G into two subgraphs, each containing at most 2N/3 vertices. They also present a linear-time algorithm to compute √sucha separator. In [20], it is shown that every graph of genus g has a 2 gN and that such a separator can be computed in linear time. In [2], a 3 -separator of size O 2
p linear-time algorithm for computing a t-separator of size O (g + 1/t)N for an embedded graph of genus g is given; for 0 < t < 1, a t-separator is a vertex set whose removal partitions G into subgraphs of size at most tN . Other results deal with the problems of computing small simple-cycle separators of planar graphs [29], edge separators of planar graphs [15], separators of planar graphs with negative or multiple vertex weights [17], and separators of low cost [3, 16]. In [24], the first I/O-efficient algorithm for computing planar separators is presented. This algorithm, which is an external version of Lipton and Tarjan’s algorithm, computes a 32 -separator √ of size O N and takes O(sort(N )) I/Os, provided that a planar embedding and a BFS-tree of the graph are given. In [5], an external version of Goodrich’s multi-way separator algorithm [21] p has been developed. This algorithm computes a t-separator of size O (N/B) log M/B (N/B) + N/t and takes O(sort(N )) I/Os, again assuming that an embedding and a BFS-tree are given. A number of subsequent papers develop a hierarchy of reductions that lead to O(sort(N ))I/O algorithms for a variety of fundamental problems on embedded planar graphs, if an optimal separator decomposition can be obtained in O(sort(N )) I/Os: In [5, 8], separator-based ideas first pioneered in [19] are used to obtain I/O-efficient shortest-path algorithms for undirected and directed planar graphs. These algorithms can of course also be used to compute BFS-trees of planar graphs. In [6], a DFS-algorithm for undirected planar graphs is presented, which uses BFS in the dual and, hence, also depends on planar separators. The directed DFS-algorithm of [9] needs to compute directed spanning trees of the graph; currently the only I/O-efficient algorithm for this problem is the shortest-path algorithm of [8]. Other I/O-efficient algorithms for planar graphs that rely on separators are the strong connectivity algorithm of [9] and the algorithms of [7, 8] for topologically sorting planar directed acyclic graphs. While the shortest-path algorithms of [5, 8] perform only O(sort(N )) I/Os, they take O(N log N + N B) computation time in internal memory. To highlight the I/O-complexity as well as the internal-memory computation time of an algorithm, we say that an algorithm has I/O-complexity O(sort(N )) if it performs O(sort(N )) I/Os and O(N log N ) computation steps; if it performs O(sort(N )) I/Os and its computation time is within a constant factor of the computation time of the best shortest-path algorithm for planar graphs that performs O(sort(N )) I/Os, given an appropriate separator decomposition of the graph, we say that the algorithm has I/O-complexity O(sssp(N )).
1.2
New Results
The main result of our paper is an algorithm that, given a planar graph G with N vertices and an √ integer r > 0, computes a vertex separator S of size O (N/ r) and whose removal partitions G into √ O(N/r) subgraphs of size at most r and boundary size O ( r). The algorithm takes O(sort(N )) I/Os, provided that the internal memory has size at least 56r log2 B. The most interesting value of r is B 2 , because this is the granularity of the partition required for all separator-based I/O-efficient algorithms for planar graphs that have been developed so far. At the end of the paper, we show how to use a bootstrapping approach based on our second algorithm, discussed next, in order to reduce the memory requirements from Ω(B 2 log2 B) to Ω(B 2 ) in this case. This, however, comes at the expense of increasing the complexity of the algorithm to O(sssp(N )). Thanks to our algorithm, a wide variety of problems, as discussed in the previous section, can be solved in O(sssp(N )) I/Os if M = Ω(B 2 ). In particular, a shortest-path tree of a planar graph can be obtained in this complexity. Using this fact, we show the following I/O-efficient versions of results from [3]: 3
+ Let G = (V, E) be a planar graph with N vertices, let w : V → R+ 0 and c : V → R0 be assignments of non-negative weights 0 < t < 1 be an P and costs to the vertices of P G, and let 2 arbitrary constant. Let w(G) = w(v), and let C(G) = (c(x)) . If the size of the x∈V x∈V internal p memory is Ω(B 2 ), it takes O(sssp(N )) I/Os to compute a vertex separator S of cost c(S) ≤ 4 2 · C(G)/t such that no connected component of G − S has weight exceeding tw(G). If all vertices have weight and cost equal to 1, and by choosing t = r/N , we obtain a separator of size √ O(N/ r) that partitions the graph into pieces of size at most r. This matches the result produced by our first algorithm, but without requiring that M ≥ 56r log2 B. Another consequence is the following edge separator result: Let G = (V, E) be a planar graph with N vertices, let w : V → R+ 0 be an assignment of non-negative weights to the vertices of G, and let 0 < t < 1 be an arbitrary constant. Let P w(G) = w(x). If w(x) ≤ tw(G) for every vertex x ∈ V , there exists an edge separator x∈V q P 2 S ⊆ E of size |S| ≤ 4 2 x∈V (deg(x)) /t such that no connected component of G − S has weight exceeding tw(G). Such a separator can be computed in O(sssp(N )) I/Os, provided that M = Ω(B 2 ). The presentation of these results is organized as follows: In Section 2, we introduce the necessary terminology and notation and discuss some technical results that will be useful in our algorithms. In Section 3, we discuss a graph contraction procedures that will be used many times in our algorithms. Our algorithm for partitioning an unweighted planar graph is presented in Section 4. The partition produced by the algorithm will not have all the properties required by the shortestpath algorithm of [5] or any of the other separator-based I/O-efficient algorithms for planar graphs [7, 8, 9]. In Section 5, we explain how to ensure the required additional properties. In Section 6, we discuss our I/O-efficient algorithm for computing separators of planar graphs with costs and weights. In Section 7, we explain how to combine the algorithms from Sections 4 and 6 to reduce the memory requirements of our unweighted separator algorithm. We conclude with a discussion of open problems in Section 8.
2 2.1
Preliminaries Graphs and Planarity
We assume that the reader is familiar with standard graph-theoretic terms and notation as defined, for example, in [22, 31]. In this paper, all graphs are simple, that is, do not contain parallel edges or loops, even though the results are easy to generalize to multigraphs. For a set W ⊆ V of vertices, we use G[W ] to denote the subgraph of G with vertex set W and whose edge set consists of all edges in G that have both endpoints in W ; we call G[W ] the subgraph of G induced by vertex set W . For a set of vertices W ⊆ V , let G − W = G[V \ W ]. For a vertex x ∈ V , let G − x = G − {x}. For a set of edges F ⊆ E, let G − F = (V, E − F ). For a vertex x ∈ G, the (open) neighbourhood N (x) of x is the set of vertices adjacent to x, that is, N (x) = {y ∈ V (G) : xy ∈ E} \ {x}; the closed neighbourhood Sof x is N [x] = {x} ∪ N (x). We generalize this to vertex sets and subgraphs by defining N [V ′ ] = x∈V N [x], N (V ′ ) = N [V ′ ] \ V ′ , N [G′ ] = G[N [V ′ ]], and N (G′ ) = G[N (V ′ )], where G′ = (V ′ , E ′ ). We often call N (G′ ) the boundary of G′ . The degree deg(x) of a vertex x is the number of edges incident to x. If G is simple, we have deg(x) = |N (x)|. A graph G is planar if it can be drawn in the plane so that the edges of G do not intersect, except 4
at their endpoints. Such a drawing of G is called a topological embedding of G. We denote it by E(G). Every topological embedding of G defines an order of the edges incident to each vertex x ∈ G, clockwise around x. A representation of these orders for all vertices x ∈ G is called a combinatorial ˆ Given a topological embedding E(G) consistent with a embedding of G, which we denote by G. ˆ ˆ The combinatorial embedding G of G, we call the connected regions of R2 \ E(G) the faces of G. ˆ ˆ By size of a face of G is the number of edges on its boundary. Let F denote the set of faces of G. Euler’s formula, |V | + |F | − |E| = 2. In particular, |E| ≤ 3|V | − 6. We define the size |G| of a planar graph G = (V, E) to be the number of vertices in G. For an embedded planar graph G = (V, E) and an edge e ∈ E, the dual e∗ of e is the edge f1 f2 , ˆ that have edge e on their boundary. The dual of G, then, where f1 and f2 are the two faces of G ∗ ∗ is the multigraph G = (F, E ), where E ∗ = {e∗ : e ∈ E}. A partition of a set S is a collection S = {S1 , . . . , Sk } of subsetsSof S so that every element of S belongs to exactly one set Si , that is, Si ∩ Sj = ∅, for i 6= j, and ki=1 Si = S. Given a graph G = (V, E) and a partition V = {V1 , . . . , Vk } of the vertex set of G, the contraction ′ = {V V : ∃ xy ∈ E s.t. x ∈ V and y ∈ V }. If the of V in G is the graph G/V = (V, E ′ ), where EP i j i j vertices of G have weights, we define w(Vi ) = x∈Vi w(x), for all 1 ≤ i ≤ k. If the graph G[Vi ] is connected, for all 1 ≤ i ≤ k, we call G/V an edge contraction. If there exist vertex sets X1 , . . . , Xk such that, for all 1 ≤ i ≤ k and x ∈ Vi , N (x) \ Vi = Xi , that is, if all vertices in Vi have the same neighbours in V (G) \ Vi , we call G/V a vertex bundling. We will use the following facts. Fact 2.1 If G is planar, then any edge contraction or vertex bundling of G is planar. S Fact 2.2 Let S ⊆ V, let S = Vi ∈S Vi , let Vi , Vj 6∈ S, and let x ∈ Vi and y ∈ Vj . If Vi and Vj belong to different connected components of (G/V) − S, then x and y belong to different connected components of G − S.
2.2
Graph Separators
Given an assignment w : V → R+ 0 of weights to the vertices of a graph G = (V, E) and a constant 0 < t < 1, we call a set S ⊆ V of vertices a t-vertex separator of G if no connected component of P G − S has weight greater than tw(G), where w(G) = x∈V w(x) is the weight of G. Similarly, a t-edge separator of G is a set S ⊆ E of edges so that no connected component of the graph G − S has weight exceeding tw(G). Since we are interested mainly in vertex separators in this paper, we refer to them simply as separators. If G is unweighted, we assume that every vertex of G has weight one. In our separator algorithm for unweighted graphs, we will apply the following result to a compressed version of the graph we want to partition, in order to obtain a first separator that is then refined during a sequence of refinement steps. Theorem 2.1 (Aleksandrov and Djidjev [2]) Given a planar graph G of size N , an assignment w : V →p R+ 0 of weights to the vertices of G, and a constant 0 < t < 1, a t-vertex separator of size at most 4 N/t for G can be computed in linear time. By grouping the connected components of G − S, where G is an unweighted graph and S is a t-separator of G, we obtain a tN -partition of G. Precisely, let r > 0 be an integer, let t = r/N , and let S be a t-separator of G. Then an r-partition of G is a pair P = (S, {G1 , . . . , Gq }) with the following properties: 5
Figure 2.1. A regular partition. The solid regions are connected. Each of the hatched regions is disconnected, but shares its boundary with at most two solid regions and no hatched region.
(i) {V (G1 ), . . . , V (Gq )} is a partition of V (G) \ S, (ii) N (V (Gi )) ⊆ S, for all 1 ≤ i ≤ q, and (iii) |Gi | ≤ r, for all 1 ≤ i ≤ q. The second condition captures that every subgraph Gi is a collection of connected components of G − S, that is, no connected component of G − S has vertices in two such subgraphs. √ If G is a planarP graph, we call an r-partition P = (S, {G1 , . . . , Gq }) normal if |S| = O(N/ r), √ q = O(N/r), and qi=1 |N (Gi )| = O (N/ r). A normal r-partition P = (S, {G1 , . . . , Gq }) is c√ proper, for some constant c > 0, if |N (Gi )| ≤ c r, for all 1 ≤ i ≤ q. If we do not want to specify c, we say that P is proper. A proper r-partition is stronger than a normal r-partition because a normal r-partition may contain subgraphs with a large boundary, as long as other subgraphs have smaller boundaries; in a proper r-partition, on the other hand, every individual subgraph has to have a small boundary. Finally, we call an r-partition P = (S, {G1 , . . . , Gq }) regular if, for all 1 ≤ i ≤ q, one of the following conditions holds: (i) Graph N [Gi ] is connected, or (ii) There are at most two indices 1 ≤ j < k ≤ q, i 6∈ {j, k}, such that N (V (Gi )) ∩ N (V (Gj )) 6= ∅ and N (V (Gi )) ∩ N (V (Gk )) 6= ∅. In this case, N [Gj ] and N [Gk ] are connected. This concept is visualized in Figure 2.1, which is reproduced from Frederickson [19], who shows that every planar graph has a proper r-partition and every planar graph of bounded degree has a regular proper r-partition. The following result states that a proper r-partition of a planar graph can be obtained efficiently: Theorem 2.2 (Frederickson [19]) Given a planar graph G of size N and a normal r-partition P = (S, {G1 , . . . , Gp }) of G, a proper r-partition P ′ = (S ′ , {G′1 , . . . , G′q }) of G such that S ⊆ S ′ can be computed in O(N log N ) time. Frederickson also shows how to obtain a normal r-partition of a planar graph G in O(N log N ) time, which, together with Theorem 2.2, implies that a proper r-partition of G can be computed in O(N log N ) time. To prove Theorem 2.2, Frederickson considers each graph Gi in turn and 6
√ partitions it into subgraphs of boundary size O( r). When partitioning Gi , the algorithm requires knowledge only of N [Gi ]. Thus, if |N [Gi ]| ≤ M , for all 1 ≤ i ≤ p, we can implement Frederickson’s procedure by loading each graph N [Gi ] into internal memory and partitioning Gi without incurring any further I/Os. Assuming that each graph N [Gi ] is stored in consecutive memory locations, we thus have Corollary 2.1 Given a planar graph G of size N and a normal r-partition P = (S, {G1 , . . . , Gp }) of G, a proper r-partition P ′ = (S ′ , {G′1 , . . . , G′q }) of G such that S ⊆ S ′ can be computed in O(N/B) I/Os and O(N log N ) time, provided that |N [Gi ]| ≤ M for all 1 ≤ i ≤ p.
2.3
Bipartite Planar Graphs
A graph G = (V, E) is bipartite if the vertex set V can be partitioned into two sets U and W such that x ∈ U and y ∈ W , for every edge xy ∈ E. In this case, we write G = (U, W, E). We use the following two simple results to bound the sizes of certain bipartite graphs in different parts of our algorithms. Lemma 2.1 Let G = (U, W, E) be a simple connected bipartite planar graph such that every vertex in W has degree at least three. Then |W | ≤ 2|U |. ˆ of G. Since G is bipartite, every face of G ˆ has size at least Proof. Consider a planar embedding G 4. Thus, |F | ≤ |E|/2. By Euler’s formula, |V | + |F | − |E| = 2, that is, 2 = |V | + |F | − |E| ≤ |V | − |E|/2
|E| ≤ 2|V |. On the other hand, |E| ≥ 3|W |, so that 3|W | ≤ 2|V |
= 2(|U | + |W |)
|W | ≤ 2|U |.
Corollary 2.2 Let G = (U, W, E) be a simple connected bipartite planar graph such that no two vertices x, y ∈ W satisfy N (x) = N (y) and deg(x) = deg(y) ≤ 2. Then |G| ≤ 7|U |. Proof. We have to prove that |W | ≤ 6|U |. To this end, we divide W into three subsets and bound the size of each of these sets. Let W1 be the set of degree-1 vertices in W , let W2 be the set of degree-2 vertices in W , and let W3 = W \ (W1 ∪ W2 ), that is, every vertex in W3 has degree at least three. Since there are no two vertices x, y ∈ W with deg(x) = deg(y) = 1 and N (x) = N (y), W1 contains at most |U | vertices, one per vertex in U ; see Figure 2.2(a). To count the vertices in W3 , we consider the bipartite planar graph G3 = (U3 , W3 , E3 ) induced by all edges incident to vertices in W3 ; see Figure 2.2(b). By Lemma 2.1 and because U3 ⊆ U , we have |W3 | ≤ 2|U3 | ≤ 2|U |. 7
(a)
(b)
(c)
(d)
Figure 2.2. Illustration of the proof of Corollary 2.2. Figure (a) shows a bipartite planar graph G = (U, W, E); the white vertices are in U ; the black ones are in W . The circled vertices are in W1 . Figure (b) shows the subgraph G3 of G induced by all edges incident to vertices in W3 . Figure (c) shows the subgraph G2 of G induced by all edges incident to vertices in W2 . Figure (d) shows the graph H2 obtained from G2 by contracting the highlighted edges in Figure (c).
To count the vertices in W2 , consider the graph H2 = (U2 , E2 ), where U2 = N (W2 ) ⊆ U and E2 = {xz : there exists a vertex y ∈ W2 with N (y) = {x, z}}; see Figure 2.2(d). Since there are no two vertices x, y ∈ W2 with N (x) = N (y), H2 contains exactly one edge per vertex in W2 , that is, |E2 | = |W2 |. Next we argue that graph H2 is planar, which implies, by Euler’s formula, that |W2 | = |E2 | ≤ 3|U2 | ≤ 3|U |. To see that H2 is planar, consider the subgraph G2 of G induced by all edges incident to vertices in W2 ; see Figure 2.2(c). Since G is planar, G2 is planar. H2 can be obtained from G2 by contracting one of the edges incident to each vertex y ∈ W2 . By Fact 2.1, this implies that H2 is planar. In summary, we have |W | = |W1 | + |W2 | + |W3 | ≤ |U | + 3|U | + 2|U | = 6|U |, that is, |G| = |U | + |W | ≤ 7|U |.
2.4
Primitive Operations
Our algorithms will make frequent use of a number of primitive operations. In order to avoid discussing their implementation repeatedly, we do so here and then refer to this section whenever we make use of such an operation. 8
Set operations. All elementary operations on two sets A and B—union, intersection, difference, etc.—can be computed in O(sort(N )) I/Os if the two sets A and B are represented as unordered sequences of elements: Sort A and B (assuming that every element is represented by a unique integer ID). Then scan the two sorted lists to produce C = A ⊙ B, where ⊙ ∈ {∩, ∪, \}. Even though not a set operation as such, we want to mention duplicate removal here: Some operations may produce multi-sets. In order to obtain a proper representation of the set of elements in such a multi-set, we need to remove duplicates. This can be done in O(sort(N )) I/Os by sorting and scanning the multi-set. Copying labels. Since pointers are mostly useless in I/O-efficient graph algorithms, graphs are often represented as an (unsorted) list of vertices, each with a unique vertex ID, and an (unsorted) list of edges, each labelled with the IDs of its two endpoints. Edges do not store any pointers to their endpoints. Thus, if certain labels are assigned to the vertices of the graph, the edges have no knowledge of the labels of their endpoints. However, it takes O(sort(N )) I/Os to label all edges with the labels of their endpoints: Sort the vertices by their IDs. Designate one endpoint of every edge as being the first endpoint. Then sort the edges by the IDs of their first endpoints. Now scan the sorted vertex and edge sets to label every edge with the label of its first endpoint. To label the edges with the labels of their second endpoints, sort the edges by the IDs of their second endpoints, and repeat the copying process. Graph contraction. Given a labelling of the vertices of graph G that represents a partition V = {V1 , . . . , Vk } of the vertex set of G, that is, that assigns the same label to two vertices if and only if they belong to the same set Vi ∈ V, the graph G/V can be computed in O(sort(N )) I/Os: First label the edges of G with the labels of their endpoints. Now replace every vertex with its ID and every edge xy with the edge ab, where a is the label of x and b is the label of y. Finally, remove duplicates from the resulting vertex and edge sets. In this paper, we choose the label of a set Vi ∈ V to be the ID of a representative x ∈ Vi . We will then often refer to Vi as the vertex x, taking the point of view that x has survived the contraction and all other vertices in Vi have been contracted into x. Connected components. Chiang et al. [14] proved that it takes O(sort(N )) I/Os and O(N log N ) time to compute the connected components of a planar N -vertex graph G, that is, to compute a labelling of the vertices of G such that two vertices have the same label if and only if they are connected.
3
Uniform Graph Contraction
In this section, we discuss a general compression procedure for planar graphs that will be used repeatedly in our algorithms. In general, graph compression is achieved in I/O-efficient algorithms by repeatedly contracting edges until some goal is reached (usually a sufficient reduction of the size of the graph). Since it would be inefficient to contract edges one at a time, edges need to be contracted simultaneously. More precisely, one computes an edge contraction G/V of G such that |V| ≤ c|V |, for some c < 1, that is, G/V has only a constant fraction of the vertices of G. The algorithms of [5, 14, 30] for computing connected components and minimum spanning trees are based on exactly this idea. However, the partition V used in these algorithms is non-uniform in 9
the sense that some sets Vi ∈ V may be large, while others may be small; that is, some vertices in G/V represent many vertices in G and others represent only few. As we will see, our separator algorithm for unweighted graphs will rely heavily on the compression being uniform, that is, on every set Vi ∈ V having constant size. In order to achieve uniformity, while still guaranteeing that |V| ≤ c|V |, for some c < 1, we apply two contractions: an edge contraction, followed by a vertex bundling. In Section 3.1, we give a high-level description of our uniform contraction procedure and prove a general bound on the size of the compressed graph it produces. In Section 3.2, we show how to implement this procedure in O(sort(N )) I/Os on an N -vertex planar graph.
3.1
The High-Level Procedure
Our graph contraction procedure takes as input a weighted planar graph G and a set of weight thresholds u1 , . . . , uk . More precisely, every vertex x has multiple weights w1 (x), . . . , wk (x), and every vertex x in G satisfies wh (x) ≤ uh , for all 1 ≤ h ≤ k. Our contraction procedure will ensure that the same is true for every vertex in the graph it produces from G. Every vertex that satisfies these weight contraints is said to be within bounds. A vertex x that is within bounds is light if wh (x) ≤ uh /2, for all 1 ≤ h ≤ k, and heavy otherwise. Intuitively, we will use these weight thresholds to ensure that no vertex in the final compressed graph represents more than a constant number of vertices in G, and that the compressed graph satisfies other properties. By choosing the thresholds large enough, we reduce the number of heavy vertices, which, together with Lemma 3.1 below, gives us a bound on the size of the compressed graph. The contraction procedure consists of two phases: The edge contraction phase computes an edge contraction G1 = G/V1 of G such that all vertices of G1 are within bounds and every edge of G1 has at least one heavy endpoint. The bundling phase computes a vertex bundling G2 = G1 /V2 of G1 such that all vertices of G2 are within bounds and there are no two light vertices x, y ∈ G2 such that N (x) = N (y) and deg(x) = deg(y) ≤ 2. Graph G2 is the final graph we return. When we later apply this procedure, we will be able to establish a bound on the number of heavy vertices in G2 . Together with the following lemma, this gives a bound on the size of this graph. Lemma 3.1 If G is planar, then G2 is planar. All vertices in G2 are within bounds. If h is the number of heavy vertices in G2 , then |G2 | ≤ 7h. Proof. The above explanation of the two phases of the procedure states explicitly that all vertices in G2 are within bounds. Graph G1 is an edge contraction of G, and G2 is a vertex bundling of G1 . Thus, if G is planar, Fact 2.1 implies that G1 is planar and, thus, that G2 is planar. To bound the size of G2 , we consider the subgraph G′ of G2 induced by all edges incident to light vertices and prove that G′ satisfies the conditions of Corollary 2.2 with U being the set of heavy vertices in G′ and W being the set of light vertices in G′ . Thus, |G′ | = |U | + |W | ≤ 7|U |. Since all light vertices of G belong to W and all vertices in U are heavy, this implies that |G| = h + |W | ≤ h + 6|U | ≤ 7h. To prove that G′ is bipartite with U being the heavy vertices in G′ and W being the light vertices in G′ , observe that every edge in G′ has at least one light endpoint. So there are no two adjacent heavy vertices. Now assume for the sake of contradiction that there are two light vertices 10
V1 and V2 in G2 that are adjacent. This implies that there exist two adjacent vertices x, y ∈ G1 such that x ∈ V1 and y ∈ V2 . Moreover, since wh (x) ≤ wh (V1 ) and wh (y) ≤ wh (V2 ), for all 1 ≤ h ≤ k, both x and y are light. This is a contradiction because G1 contains no two adjacent light vertices. By the definition of G2 , there are no two light vertices in G′ that have degree at most two and have the same neighbours. Hence, G′ satisfies the conditions of Corollary 2.2.
3.2
I/O-Efficient Implementation
In this section, we discuss how to implement the two phases of the contraction procedure in O(sort(N )) I/Os. 3.2.1
Edge Contraction Phase
To implement the edge contraction phase, we compute a set F of edges and define V1 to be the partition of V corresponding to the connected components of (V, F ). We will often use VF to denote this partition. The set F will have the property that the graph (V, F ) is a forest, which makes the computation of connected components and, thus, the computation of the partition V1 easy [14]. The set F will not necessarily be a subset of E. However, whenever we add an edge xy to F , we ensure that the two sets V1 and V2 in VF such that x ∈ V1 and y ∈ V2 contain two vertices x′ ∈ V1 and y ′ ∈ V2 such that x′ y ′ is an edge of G. Hence, if G[V1 ] and G[V2 ] are connected, so is G[V1 ∪ V2 ], that is, as we augment F , we maintain that G/VF is an edge contraction of G. We compute the edge set F iteratively. Each iteration computes a set F ′ of edges such that G/VF ∪F ′ is an edge contraction and each of its vertices is within bounds. The edges in F ′ are then added to F . This iterative process stops as soon as every edge in G/VF has at least one heavy endpoint, at which point we define G1 = G/VF . To efficiently compute the set F ′ , each iteration consists of three steps: The first step extracts the contractible subgraph H of G/VF , where an edge of G/VF is contractible if both its endpoints are light and H is the subgraph of G/VF induced by all contractible edges. The second step computes a matching F1′ of H and contracts the edges in F1′ , that is, computes the graph H1 = H/VF1′ . We call a vertex in H1 matched if it represents two vertices in H, that is, is the result of contracting an edge in F1′ ; otherwise the vertex is unmatched. Note that all neighbours of an unmatched vertex are matched because F1′ is maximal. The third step adds edges between matched and unmatched vertices to a set F2′ so that every non-singleton set in VF2′ contains exactly one matched vertex. During this third step, we maintain the invariant that the matched vertex in such a set stores the weights of the whole set. To determine which edges to add to F2′ , each unmatched vertex x is inspected in turn. If there is a matched neighbour y of x that is light (that is, the whole set in VF2′ containing y is light), we add the edge xy to F2′ . To indicate that x is now a member of the set in VF2′ containing y, the weights of y are increased by the corresponding weights of x. After this third step, we define F ′ = F1′ ∪ F2′ and add the edges in F ′ to F . This finishes the iteration. Given the definition of graph H, the graph G/VF contains two adjacent light vertices if and only if H is non-empty. Thus, in order to decide whether another iteration is required, we can test whether H is empty. Also, if H is the contractible subgraph of G/VF and H ′ is the contractible subgraph of G/VF ∪F ′ , it is easy to see that H ′ is in fact a subgraph of H/VF ′ ; that is, to compute the contractible subgraph used in the next iteration, H ′ , it suffices to compute H/VF ′ and extract its contractible subgraph. Moreover, we have H/VF ′ = H1 /VF2 . So it suffices to compute the latter. Thus, at no time do we have to work with the whole graph G; it suffices to work with the 11
Procedure ContractEdges Input:
A weighted graph G = (V, E) and a set of weight thresholds based on which every vertex in G is classified as light or heavy. Output: An edge contraction G1 = G/VF of G. H←G 2: F ← ∅ 3: while H is not empty do 4: Step 1: Extract the contractible subgraph 1:
H ← the contractible subgraph of H 5:
Step 2: Contract a matching Compute a maximal matching F1′ of H H1 ← H/VF1′
6:
Step 3: Contract edges incident to unmatched vertices F2′ ← ∅ for every unmatched vertex x ∈ H1 do if x has a light neighbour y (which is matched) then Add edge xy to F2′ and increase the weights of y by the corresponding weights of x. end if end for F ← F ∪ F1′ ∪ F2′ H ← H1 /VF2′
end while 8: G1 ← G/VF 7:
Algorithm 3.1. The edge contraction phase.
contractible subgraph H of G/VF . We will prove below that the size of H decreases by a factor of at least two in each iteration. This will lead to a geometrically decreasing cost of the iterations of the loop and is the key to the I/O-efficiency of the algorithm. Algorithm 3.1 shows the pseudo-code of our procedure. Before providing the implementation details and analyzing the I/O-complexity of the procedure, we show that it correctly implements the edge contraction phase of our uniform graph contraction procedure. Lemma 3.2 Let G1 be the graph produced by procedure ContractEdges. Then G1 is an edge contraction of G, every vertex of G1 is within bounds, and every edge of G1 has at least one heavy endpoint. Proof. We prove by induction on the number of iterations that the graph G/VF is an edge contraction of G all of whose vertices are within bounds. Since we exit with G1 = G/VF only when every edge in G/VF has a heavy endpoint, this proves the lemma. The claim is true before the first iteration because F = ∅, that is, G/VF = G, and all vertices of G are within bounds. So assume that the claim is true before the current iteration. Then every set in VF induces a connected subgraph. Every edge xy ∈ F1′ is an edge of H ⊆ G/VF . Hence, there 12
exists an edge x′ y ′ ∈ E and two sets V1 , V2 ∈ VF such that x, x′ ∈ V1 and y, y ′ ∈ V2 . By adding edge xy to F1′ , the sets V1 and V2 are merged into the set V1 ∪ V2 in VF ∪F1′ . Since, by the induction hypothesis, the graphs G[V1 ] and G[V2 ] are connected, so is the graph G[V1 ∪ V2 ] because x′ y ′ ∈ E; that is, G/VF ∪F1′ is an edge contraction. Every vertex in G/VF ∪F1′ is within bounds because each of its vertices represents at most two vertices in G/VF and, if it represents two vertices, they must belong to the contractible subgraph, that is, must be light. Since H1 ⊆ G/VF ∪F1′ , and we add only edges of H1 to F2′ , we can argue as in the previous paragraph that every set in VF ∪F1′ ∪F2′ induces a connected subgraph of G. Hence, G/VF ∪F1′ ∪F2′ is an edge contraction. Before the third step, every vertex in H1 stores the total weights of all the vertices in G it respesents. Since F2′ = ∅ before the first step, every set in VF2′ is a singleton, and we can view every matched vertex in H1 as storing the total weight of all vertices in the set in VF2′ containing it. We maintain this invariant throughout the third phase. Before adding an edge xy to F2′ in the third step, where x is unmatched and y is matched, we test whether y is light, that is, whether the set in VF2′ containing y is light, and we add edge xy to F2′ only if this is the case. Therefore, the set in VF2′ containing vertex y, and thus the corresponding vertex in H1 /VF2′ , remains within bounds after the addition of edge xy. Since no edge added to F2′ produces a set in VF2′ that is out of bounds, all vertices in H1 /VF2′ are within bounds at the end of the loop. Procedure ContractEdges is fairly easy to implement in O(sort(N )) I/Os. To prove this, we show how to implement every iteration of the while-loop in Lines 3–7 in O(sort(|H|)) I/Os, that |H| decreases by a factor of at least two from one iteration to the next, and that the rest of the algorithm takes O(sort(N )) I/Os. We start by analyzing the I/O-complexity of one iteration of the while-loop. Extracting the contractible subgraph. The contractible subgraph of H can be extracted in O(sort(|H|)) I/Os: First we label all edges with the weights of their endpoints, and then we scan the edge set to discard all edges with at least one heavy endpoint. The result is the edge list of the contractible subgraph. Now we scan this edge list and create a list of their endpoints. To produce the vertex list of H, we remove duplicates from the resulting list. As discussed in Section 2.4, all steps of this construction take O(sort(|H|)) I/Os. Computing and contracting a matching. Zeh [33] presents an algorithm that computes a maximal matching of a graph G = (V, E) in O(sort(N )) I/Os, where N = |V | + |E|. Since H is planar, we have N = O(|H|) when applying this procedure to H. Hence, the matching can be computed in O(sort(|H|)) I/Os. Once the matching is given, its edges can be contracted in O(sort(|H|)) I/Os, using the contraction procedure from Section 2.4. Contracting edges between matched and unmatched vertices. To contract edges between matched and unmatched vertices, that is, to implement Step 3 of the iteration, we start by extracting all edges in H1 that are incident to unmatched vertices. For the resulting bipartite graph H ′ , we compute the following information: Let Vm be the set of matched vertices, and let Vu be the set of unmatched vertices in H ′ . We number the vertices in Vm as y1 , . . . , yr and the vertices in Vu as x1 , . . . , xs , in an arbitrary order. We sort the edges in H ′ by their unmatched endpoints as primary keys and by their matched endpoints as secondary keys, and store for every edge xi yj the unmatched endpoint xi′ of the next edge incident to yj ; that is, if yj is adjacent to vertices
13
xi1 , . . . , xit with i1 < · · · < it , then, for 1 ≤ h < t, edge xih yj stores the ID of vertex xih+1 . Edge xit yj stores nil to indicate that it is the last edge incident to yj . This information can easily be computed in O(sort(|H ′ |)) I/Os: We sort the edges by their matched endpoints as primary key and by their unmatched endpoints as secondary key. Then we scan the sorted edge list to compute for every edge xi yj the endpoint of the next edge incident to yj . (If the next edge in the sorted sequence is xi′ yj , then this endpoint is xi′ . If the next edge is xi′ yj ′ with j ′ 6= j, then edge xi yj stores nil.) Now we sort the edges by their unmatched endpoints as primary key and by their matched endpoints as secondary key. Given that graph H ′ has been prepared in this manner, we contract edges as follows: We scan the sorted edge list, that is, we inspect the unmatched vertices in sorted order and scan their adjacency lists. For every vertex xi , as soon as we find an edge xi yj , where yj is light, we contract xi into yj , that is, we increase each weight wh (yj ) of vertex yj by the corresponding weight wh (xi ) of xi and add the edge xi yj to F2′ . The remaining edges in xi ’s adjacency list are then ignored. In order to implement this procedure correctly, we have to have a mechanism to inform subsequent edges incident to a vertex yj about the change of its weights resulting from the contraction of vertex xi into yj . We use a priority queue Q to do this. In particular, we initialize Q to contain the weights of vertices y1 , . . . , yr , where the priority of yj is equal to the ID of the first edge xi yj incident to yj . For every edge xi yj inspected during the scan, we perform a Delete-Min operation on Q to retrieve the current weights of yj . If edge xi yj is contracted, the weights of yj are updated. Otherwise, they remain unchanged. Then, if edge xi yj stores a vertex xi′ 6= nil as the next unmatched vertex incident to yj , we insert the updated weights of yj into Q, now with priority xi′ yj . The whole procedure requires one scan of the sorted edge list of H ′ and two priority queue operations per edge, once the edges of H ′ are stored in the right order and store the appropriate successor pointers as defined above. Using a buffer tree [4], to implement the priority queue, every priority queue operation takes O((1/B) log M/B (r/B)) = O((1/B) log M/B (|H ′ |/B)) I/Os amortized. Thus, the contraction of edges between matched and unmatched vertices takes O(sort(|H ′ |)) = O(sort(|H|)) I/Os. Total cost of the loop. The previous three paragraphs establish that each iteration of the whileloop takes O(sort(|H|)) I/Os. Also observe that |H| ≤ N before the first iteration. To prove that the cost of the whole loop is O(sort(N )) I/Os, it is therefore sufficient to show that |H| decreases by a factor of at least two from one iteration to the next. Lemma 3.3 The loop in Lines 3–7 of procedure ContractEdges takes O(sort(N )) I/Os. Proof. Let H (1) , . . . , H (k) be snapshots of H after Step 1 of the different iterations, and let H (0) = G be a snapshot of H at the beginning of the first iteration. Then the total cost of Step 1 over all Pk (0) iterations is O(sort(|H |) + i=1 sort(|H (i) |)) I/Os. The cost of Steps 2 and 3 over all iterations P is O( ki=1 sort(|H (i) |)) I/Os. Next we prove that, for 1 ≤ i < k, |H (i+1) | ≤ |H (i) |/2. Hence, Pk (i) (1) | ≤ 2N , and the total cost of the loop is O(sort(N )) I/Os. i=1 |H | ≤ 2|H So consider a particular graph H (i) , where 1 ≤ i < k. After Step 2 of the i’th iteration, there are at most |H (i) |/2 matched vertices in H1 because each of them represents two vertices in H (i) . To bound the number of vertices in H (i+1) by |H (i) |/2, we argue that every vertex in H (i+1) represents a set V ′ in VF2′ that contains a matched vertex. 14
To see that this is true, observe that we inspect every unmatched vertex x in H1 to see whether it has a matched neighbour y that is light. If so, we add the edge xy to F2′ , thereby adding x to the set in VF2′ that contains y. If not, vertex x remains in a singleton set in VF2′ . However, the corresponding vertex in H1 /VF2′ has only heavy neighbours, that is, does not belong to the contractible subgraph of H1 /VF2′ , which is H (i+1) . I/O-complexity of the edge contraction phase. To complete the analysis, we have to consider the cost of Lines 1, 2, and 8 of the algorithm. However, Lines 1 and 2 are easy to implement in O(N/B) I/Os and linear time. Line 8 requires computing the connected components of the graph GF = (V, F ). This can be done in O(sort(N )) I/Os (see Section 2.4). The connected components algorithm identifies components by labelling every vertex in a connected component of GF with a representative. As argued in Section 2.4, the graph G/VF can then be computed in O(sort(N )) I/Os. Together with Lemma 3.3, this proves Lemma 3.4 The edge contraction phase of the uniform graph contraction procedure takes O(sort(N )) I/Os. 3.2.2
Bundling Phase
The bundling phase assumes that no two light vertices in the input graph G1 are adjacent. By Lemma 3.2, this is true for the graph produced by the edge contraction phase. We first extract all light vertices of degree at most two and represent each such vertex x as a triple (x, y1 , nil) or (x, y1 , y2 ), depending on whether it has one or two (heavy) neighbours. We sort these triples by their last two components, thereby storing all vertices with the same neighbours consecutively. Then we scan this sorted list, that is, we scan each group C of vertices with the same neighbours. For each such group, we form subgroups, starting with the first vertex in C. For every group we form, we record its total weights W1 , . . . , Wk , which are the sums of the respective weights of the vertices in the group. For every inspected vertex x, we add it to the current group if Wh ≤ uh /2, for all 1 ≤ h ≤ k. Otherwise, vertex x starts a new group. Groups are represented by labelling every vertex in a group with the ID of the first vertex in the group. The final grouping represents the partition V2 of V (G1 ), and we compute the graph G2 = G1 /V2 using the graph contraction procedure from Section 2.4. Lemma 3.5 Given an N -vertex planar graph G1 that has no two adjacent light vertices and all of whose vertices are within bounds, the bundling phase takes O(sort(N )) I/Os and produces a vertex bundling G2 = G1 /V2 of G1 that contains no two light vertices x and y with N (x) = N (y) and deg(x) = deg(y) ≤ 2. All vertices in G2 are within bounds. Proof. The I/O-bound of the procedure is obvious because we sort and scan the vertex and edge sets of G1 a constant number of times and then apply the contraction procedure from Section 2.4. It is also obvious that G1 /V2 is an edge bundling because we add two vertices to the same set in V2 only if they have the same neighbours. Next assume that G2 contains two light vertices x and y such that N (x) = N (y) and deg(x) = deg(y) ≤ 2. Then x and y are the representatives of two sets V1 and V2 in V2 that are subsets of the set C of all vertices with neighbourhood N (x), and both sets are light. Assume w.l.o.g. that V1 is formed before V2 , and let z be the first vertex in C that is not in V1 . Then z is not added to 15
V1 because there exists an index h such that wh (V1 ) > uh /2. This is a contradiction because we assumed that V1 was light. Finally assume that G2 contains a vertex x that is out of bounds. Since all vertices of G1 are within bounds, x must represent some set V1 formed by merging vertices that belong to a set C of light vertices with the same neighbours. Let y be the last vertex in C that is added to V1 . Since y is light, the set V1 —and thus x—is within bounds unless there exists an index h such that wh (V1 ) > uh /2 before adding y to V1 . But in this case y would not have been added to V1 , a contradiction. From Lemmas 3.2, 3.4, and 3.5, we have Lemma 3.6 The uniform graph contraction procedure takes O(sort(N )) I/Os.
4
An Algorithm for Partitioning Unweighted Graphs
In this section, we present our main result: an I/O-efficient algorithm for computing a proper r-partition of an unweighted planar graph G. In particular, we prove the following result: Theorem 4.1 Given a planar graph G and an integer r > 0, a proper r-partition of G can be computed in O(sort(N )) I/Os, provided that M ≥ 56r log2 B. Our algorithm (Algorithm 4.1) consists of three steps. The first two steps produce a separator √ S0 of size O(N/ r) that defines an (r log2 B)-partition of G. To do so, the first step repeatedly applies the uniform contraction procedure from Section 3 to compute a hierarchy of smaller and smaller graphs. The second step then uses this hierarchy to compute the desired separator. The third step partitions each connected component of G − S0 into subgraphs of size at most r and √ boundary size O( r), adds the separator vertices this introduces to S0 , and groups subgraphs in the partition to reduce their number to O(N/r). Step 3 is easy to implement I/O-efficiently because, given the assumption that M ≥ 56r log2 B, every connected component of G − S0 fits in internal memory, which allows us to apply an internalmemory separator algorithm to each component, in order to compute the desired partition. In Steps 1 and 2, we apply the same idea iteratively. In Step 1, we construct a hierarchy of planar graphs G0 , . . . , Gℓ , where G0 = G and |Gℓ | = O(N/B). We obtain each graph Gi from the previous graph Gi−1 using the uniform graph contraction procedure from Section 3. Given the reduced size of Gℓ , we can compute an (r log2 B)-partition of Gℓ in O(N/B) I/Os by applying Theorem 2.1 to Gℓ . Let Sℓ be the set of separator vertices used in the partition. In Step 2, we undo the contraction steps that produced graphs G1 , . . . , Gℓ from G0 , one graph at a time, and, in each step, derive a separator Si for Gi from the separator Si+1 computed in the previous iteration. We do this as follows: Since Gi+1 is obtained from Gi using the graph contraction procedure from Section 3, every vertex in Gi+1 represents a set of vertices in Gi . Let Si′ be the set of vertices in Gi represented by the vertices in Si+1 . In order to obtain an (r log2 B)-partition of Gi , we partition every component of Gi − Si′ into subgraphs of size at most r log2 B and add the separator vertices used in this partition to a set Si′′ . The separator Si is the union of sets Si′ and Si′′ . S0 is the separator obtained at the end of this process. In order to carry out Step 2 efficiently, and in order to obtain a small separator S0 at the end of this phase, the graph hierarchy G0 , . . . , Gℓ has to satisfy a number of properties. 16
Procedure Separator Input: A planar graph G = (V, E) and an integer r > 0. Output: A proper r-partition P = (S, R) of G. 1:
ℓ ← ⌊log B⌋ − 1
2:
Step 1: Compute the graph hierarchy G0 ← G for i = 1, . . . , ℓ do Compute a graph Gi that satisfies Properties (GH3)–(GH6) from Gi−1 . end for
3:
Step 2: Compute the separator S0
4:
Step 3: Compute the final partition
√ Apply Theorem 2.1 to compute a separator Sℓ of size O (|Gℓ |/ ( r log B)) for Gℓ whose removal partitions Gℓ into connected components of size at most r log2 B. for i = ℓ − 1, . . . , 0 do Compute a separator Si for Gi . Separator Si consists of two sets Si′ and Si′′ . Si′ is the set of vertices represented by the vertices in Si+1 . Si′′ is the set of separator vertices introduced in order to partition the connected components of Gi − Si′ into connected components of size at most r log2 B. end for Compute the partition P = (S, R) by partitioning √ the connected components of G − S0 into O(N/r) subgraphs of size at most r and boundary size O( r) and adding the required separator vertices to S0 . Algorithm 4.1. Computing a separator for an unweighted planar graph.
First, we want every graph Gi+1 to have roughly half as many vertices as Gi . This guarantees that the cost of Steps 1 and 2 is dominated by the cost of the computation on G0 = G and, since ℓ = ⌊log B⌋ − 1, that Gℓ has size O(N/B). Second, during the construction of the separator Si from Si′ , we would like to use an internalmemory algorithm to partition each connected component of Gi − Si′ ; that is, we want each such component to fit in memory. Since Si+1 defines an (r log2 B)-partition of Gi+1 and since M ≥ 56r log2 B, every connected component of Gi − Si′ fits in memory if every vertex in Gi+1 represents at most 56 vertices in Gi . Finally, observe that, once we add a vertex x in Gi to Si , all vertices in G represented by x belong to S0 . Thus, to guarantee that S0 is small, we have to ensure that no vertex in Gi represents too many vertices of G. These conditions are formalized in the following properties we require the graph hierarchy G0 , . . . , Gℓ to have: (GH1) ℓ = ⌊log B − 1⌋, (GH2) G = G0 , (GH3) For i = 0, . . . , ℓ, Gi is planar, (GH4) For i = 0, . . . , ℓ, |Gi | ≤ 7N/2i−1 , 17
(GH5) For i = 1, . . . , ℓ, every vertex in Gi represents at most 56 vertices in Gi−1 , and (GH6) For i = 0, . . . , ℓ, every vertex in Gi represents at most 2i+1 vertices in G. In Section 4.1, we show how to compute a graph hierarchy with these properties in O(sort(N )) I/Os. In Section 4.2, we show that the desired separator S0 of G can be computed from the graph hierarchy in O(sort(N )) I/Os. In Section 4.3, we provide the details of Step 3 and show that this step can be carried out in the same I/O and time bounds as Steps 1 and 2, thereby establishing the complexity of Algorithm 4.1 claimed in Theorem 4.1.
4.1
The Graph Hierarchy
The first step of our algorithm is the computation of a hierarchy of graphs G0 , . . . , Gℓ that satisfy Properties (GH1)–(GH6). We initialize G0 = G. Then we compute each graph Gi from the previous graph Gi−1 by assigning a weight w(x) and a size s(x) to every vertex x ∈ Gi−1 and applying the uniform graph contraction procedure from Section 3 to Gi−1 . The weight w(x) is the number of vertices in G represented by x; the size s(x) is the number of vertices in Gi−1 represented by x, that is, is equal to one. To ensure Properties (GH5) and (GH6) of graph Gi , we provide the contraction procedure with a weight threshold uw = 2i+1 and a size threshold us = 56. Note that the assignment of weights and sizes to the vertices of Gi−1 before the construction of Gi is easily accomplished. Initially, we set w(x) = s(x) = 1 for every vertex x in G0 = G. Subsequently, before computing Gi from Gi−1 , the size of every vertex in Gi−1 can be reset to one in a single scan over the vertex set of Gi−1 ; as a result of the construction of Gi−1 from Gi−2 , every vertex in Gi−1 already stores the correct weight. Lemma 4.1 A graph hierarchy G0 , . . . , Gq with Properties (GH1)–(GH6) can be constructed in O(sort(N )) I/Os. Proof. First we prove that the graph hierarchy computed by the procedure we have just described has the desired properties. Properties (GH1) and (GH2) are trivially satisfied. Property (GH3) is easy to prove by induction. For i = 0, G0 = G; thus, the planarity of G implies that G0 is planar. For i > 0, the planarity of Gi follows from the planarity of Gi−1 because, by Lemma 3.1, the uniform contraction procedure preserves planarity. Properties (GH5) and (GH6) are easy to show by induction. In particular, w(x) = 1 ≤ 2, for every vertex x ∈ G0 , and Property (GH5) is vacuous in this case. When constructing Gi from Gi−1 , every vertex in Gi−1 is within bounds because, by the induction hypothesis, it has weight at most 2i and size 1 (after resetting its size to 1). Hence, by Lemma 3.1, every vertex in Gi has weight at most 2i+1 and size at most 56. It remains to show Property (GH4). For graph G0 , Property (GH4) holds because |G0 | = |G| = N ≤ 14N . To prove the claim for graphs G1 , . . . , Gℓ , let hi be the number of heavy vertices in Gi . By Lemma 3.1, each graph Gi has size at most 7hi . To prove Property (GH4), it is therefore sufficient to prove that hi ≤ N/2i−1 . We prove this claim by induction. We partition the heavy vertices into two categories. A heavy vertex of type I has weight exceeding 2i . A type-II vertex has weight at most 2i and size greater than 28. In general, graph Gi contains less than N/2i type-I vertices and less than |Gi−1 |/28 type-II vertices, that is, hi < N/2i + |Gi−1 |/28. 18
For i = 1, we obtain h1 < N/2 + N/28 < N/20 . For i > 1, we obtain N |Gi−1 | + i 2 28 N hi−1 ≤ i + 2 4 N N ≤ i + i 2 2 N = i−1 . 2
hi
0. By Corollary 2.1, this can be done in O(N/B) I/Os and O(N log N ) time and increases the size of the separator and the number of graphs in the partition by only a constant factor; that is, this final step produces a proper r-partition of G. In summary, the graph hierarchy can be constructed in O(sort(N )) I/Os. Using the graph √ hierarchy, a separator S0 of size O(N/ r) that partitions G into connected components of size at most r log2 B can be computed in O(sort(N )) I/Os. Given S0 , it takes O(sort(N )) I/Os to obtain a normal r-partition P ′ of G, augment P ′ to obtain a normal r-partition P ′′ such that |N [G′′i ]| = O(r), for every graph G′′i in P ′′ , and finally derive a proper r-partition from P ′′ . This proves Theorem 4.1.
5
Regular Partitions
Our result from the previous section provides an algorithm for computing proper r-partitions of planar graphs, as long as r is small; but the computed partitions are not necessarily regular. In general, without a bound on the degrees of the vertices in the graph, a regular proper r-partition may not exist. For planar graphs of degree three, however, regular proper r-partitions do exist [19], and the algorithms of [5, 7, 8, 9] rely on the existence of such partitions. In this section, we show how to modify the partition produced by the algorithm in Section 4 to obtain a regular proper r-partition for a planar graph of degree three. Given such a graph G, we apply Algorithm 4.1 to G to produce a proper r-partition P = (S, {G1 , . . . , Gp }) of G. We are, however, interested only in the separator S and discard the grouping of the connected components G − S into subgraphs. Next we group the connected components of G − S to obtain the desired regular proper r-partition P ′ = (S, {G′1 , . . . , G′q }). This grouping is again similar to [19]. To compute the desired grouping, we use an auxiliary graph H again. Graph H contains one vertex per connected component of G − S. There is an edge between two vertices in H if the two corresponding components of G − S share a boundary vertex. Note that, since every vertex in G has degree at most three, graph H is planar. Every vertex x in H has two weights s(x) and b(x):
24
s(x) is the size, that is, the number of vertices in the connected component represented by x; b(x) √ is the size of the component’s boundary. Note that s(x) ≤ r and b(x) ≤ c r, for some c > 0, because P is a proper r-partition. Now we apply the uniform graph contraction procedure to H, with thresholds us = r and √ ub = c r. This produces a graph H ′ each of whose vertices represents a set of vertices in H and, thus, a set of connected components of G − S. The graphs G′1 , . . . , G′q in partition P ′ are defined as the graphs represented by the vertices in H ′ . Similar to Section 4, this partition of G − S can be computed in O(sort(N )) I/Os. Theorem 5.1 Given an N -vertex planar graph G none of whose vertices has degree greater than three, and an integer r > 0, a regular proper r-partition of G can be computed in O(sort(N )) I/Os, provided that M ≥ 56r log2 B. Proof. The I/O-complexity of the procedure is easily seen to be O(sort(N )): Algorithm 4.1 has this cost, as has the computation of the connected components of G − S. Graph H is then a contraction of G w.r.t. the component labels, and graph H ′ is obtained from H using the uniform contraction procedure. The final grouping of the connected components of G − S to produce partition P ′ requires sorting and scanning sets of size O(N ) a constant number of times. √ Next we argue that the produced partition is proper. Since P is proper, we have |S| = O(N/ r). This implies that the total boundary size of the connected components of G − S cannot exceed √ O(N/ r) because every vertex in G has degree at most three and, thus, every vertex in S is adjacent to at most three connected components of G − S. This implies that there are only O(N/r) heavy vertices in H ′ : at most 2N/r vertices of size greater than r/2 and O(N/r) vertices of boundary √ size greater than c r/2. By Lemma 3.1, this implies that |H ′ | = O(N/r), that is, partition P ′ has √ O(N/r) subgraphs. No subgraph in P ′ can have size exceeding r or boundary size exceeding c r because this is true for every vertex in H and thus, by Lemma 3.1, for every vertex in H ′ . In order to prove that P is regular, we analyze the two phases of the computation of H ′ from H. The edge contraction phase of the uniform compression procedure merges only vertices that are adjacent. In G, this corresponds to merging connected components of G − S that share boundary vertices. Thus, for every graph G′′i in the resulting partition, the graph N [G′′i ] is connected. The bundling phase merges only vertices of degree at most two that have the same neighbours. Moreover, these neighbours are heavy, that is, are not merged with any other vertices in the bundling phase. Thus, the merging of vertices during the bundling phase corresponds to merging subgraphs in the current partition that have the same at most two neighbours. For a graph G′i produced during the bundling phase, let these two neighbours be G′j and G′k . Since the vertices in H that represent G′j and G′k are not merged with any other vertices during the bundling phase, N [G′j ] and N [G′k ] are connected. Graph G′i shares boundary vertices only with G′j and G′k . Hence, partition P ′ contains only subgraphs that are either connected or share boundary vertices with at most two other subgraphs, which are connected; that is, partition P ′ is regular.
6
Separators of Low Cost and Edge Separators
Aleksandrov et al. [3] have shown the following general separator theorem for planar graphs whose vertices have associated positive weights and costs. Intuitively, as in other weighted separator theorems, the weight of a vertex measures its contribution to the subgraph in the partition that contains it. The cost of a vertex measures how costly it is to include this vertex in the separator. 25
One example of the application of costs is the edge separator theorem of [3] of which Theorem 6.3 later in this section is an I/O-efficient version. Theorem 6.1 (Aleksandrov et al. [3]) Given a planar graph G = (V, E), a cost function c : + V → R+ , a weight p function w : V → R , and a real P number 02< t < 1, there exists a t-separator S of cost c(S) ≤ 4 2C(G)/t for G, where C(G) = x∈V (c(x)) . Such a separator can be computed in linear time. Several known separator theorems can be derived from Theorem 6.1 by choosing appropriate cost and weight functions. For example, Theorem 2.1 can be obtained from Theorem 6.1 by choosing c(x) = 1 for all x ∈ V , and Aleksandrov et al. have shown how to obtain a generalization of the edge separator theorem of [15] using Theorem 6.1. In this section, we show that, using the results from Sections 4 and 5, the steps of the algorithm of [3] can be carried out in O(sssp(N )) I/Os, provided that M = Ω(B 2 log2 B). This I/O-efficient version of the algorithm of [3] allows us in particular to compute a partition of G into subgraphs of √ size at most r using a separator of size at most O(N/ r). Our separator algorithm from Section 4 computes such a partition, but does so in an I/O-efficient manner only if r = O(M/ log 2 B). The algorithm in this section removes this restriction on r. We start by giving an overview of the algorithm of [3] and then discuss how to implement each of its steps in an I/O-efficient manner.
6.1
Outline of the Algorithm
The algorithm of [3] proceeds in two phases, similar to Lipton/Tarjan’s algorithm [26]. The first phase computes a spanning tree T of G and cuts it into “shallow” layers by removing vertices from T that are at roughly the same distance from the root; see Figure 6.1(a). The second phase partitions each layer using fundamental cycles. More precisely, every layer of G is re-triangulated and a new spanning tree of the layer is computed. A fundamental cycle F (e) w.r.t. the computed spanning tree then consists of a non-tree edge e and the unique simple path in the tree connecting the edge’s endpoints. The separator computed for each layer is the union of a number of fundamental cycles; see Figure 6.1(b). There are three major differences to Lipton/Tarjan’s algorithm: (1) In order to obtain a tseparator, for t < 2/3, the tree is cut into more than three layers, and each layer is partitioned using more than one fundamental cycle. (2) In order to find the fundamental cycles partitioning each layer, so-called separation trees, first introduced in [2], are used. These trees reduce the problem of finding the desired fundamental cycles to the much simpler problem of finding a t′ -edge separator in a tree. (3) Instead of using a BFS-tree to obtain the partition into shallow layers, a shortest-path tree based on the vertex costs is used. The depth of a vertex x in the tree equals the cost of all its ancestors in the tree, including x itself. Thus, if a layer is shallow, the fundamental cycles in the layer have low cost. Next we discuss the construction of the spanning tree T and the two phases computing the separator in more detail. 6.1.1
The Shortest-Path Tree
To compute the spanning tree T used in the separator algorithm, the graph G is embedded and triangulated. Let ∆ be the resulting triangulation. Then a new vertex s of cost and weight zero is added inside one of the faces of ∆, and vertex s is connected to each vertex on the boundary of
26
G0 s2
L(ℓ1 ) G1 L(ℓ2 ) G2
ℓ3 L(ℓ3 )
L(ℓ3 ) G3 G4
L(ℓ4 )
(a)
(b)
(c)
Figure 6.1. (a) The partition of G into subgraphs G0 , . . . , G4 using levels L(ℓ1 ), . . . , L(ℓ4 ). (b) The partition of G2 into subgraphs of weight at most tw(G) using fundamental cycles. The dotted edges are the ones introduced to connect all vertices that were adjacent to vertices in L(ℓ2 ) to the new root vertex s2 . The dashed edges are the non-tree edges defining the fundamental cycles that are used to partition G2 . (c) The definition of level L(ℓ3 ). The bold edges are all edges spanning distance ℓ3 . Their bottom endpoints are in L(ℓ3 ). The sets V − (ℓ3 ) and V + (ℓ3 ) are shown in light and dark grey, respectively. Note that there are no edges between V − (ℓ3 ) and V + (ℓ3 ).
the face. From now on, we use G to refer to the resulting triangulation because a separator of the triangulation is also a separator of G. Next, every edge xy of G is replaced with two directed edges xy and yx, and each directed edge xy is assigned a weight w′ (xy) = c(y), that is, the weight of every edge is equal to the cost of its target vertex. Tree T is a shortest-path tree w.r.t. edge weights w′ , rooted at vertex s. Note that the distance of a vertex x from s in T equals the cost of x’s ancestors, including x. For every vertex x ∈ G, let d(x) = distT (s, x), and let the radius of T be r(T ) = max{d(x) : x ∈ V }. 6.1.2
Cutting T into Layers
To partition T into shallow layers, appropriate distance values ℓ1 , . . . , ℓp from the root s are chosen. For each ℓi , the bottom endpoints of all edges crossing this distance value are added to the separator. More precisely, given a real number ℓ ∈ (0, r(T )], let L(ℓ) = {y : e = xy ∈ T and d(x) < ℓ ≤ d(y)}. We denote the vertices of G by s = x0 , x1 , . . . , xN so that 0 = d(x0 ) < d(x1 ) ≤ d(x2 ) ≤ · · · ≤ d(xN ) = r(T ). Then L(ℓ) = L(ℓ′ ), for all ℓ, ℓ′ ∈ (d(xi−1 ), d(xi )]. Thus, there are only N different sets L(ℓ). Every set L(ℓ) is a separator of G whose removal partitions the vertex set V into two sets V − (ℓ) = {x ∈ V : d(x) < ℓ} and V + (ℓ) = {x ∈ V : d(x) ≥ ℓ and x 6∈ L(ℓ)} so that no vertex in V − (ℓ) is adjacent to a vertex in V + (ℓ). See Figure 6.1(c). There is a trade-off between the cost of the separator used to cut G into layers and the cost of the separator used to partition the layers. By cutting G into more shallow layers, the separators used to partition the layers become cheaper, but we need to partition G into more layers, thereby increasing the size of the separator introduced in the current phase. As we will see, this trade-off 27
p is balanced by partitioning G into p = ⌊r(T )/h⌋ layers of height h = tC(G)/8. Now let ℓ′i = ih, for 0 ≤ i ≤ p, and let Vi be the set of vertices x ∈ V such that d(x) ∈ (ℓ′i−1 , ℓ′i ], for 1 ≤ i ≤ p. For 1 ≤ i ≤ p, let xi ∈ Vi be the vertex that minimizes c(L(d(xi ))), and let ℓi = d(xi ); that is, L(ℓi ) has minimal cost among all sets L(ℓ) with ℓ′i−1 < ℓ ≤ ℓ′i . The separator S1 then is the p set S1 = L(ℓ1 ) ∪ · · · ∪ L(ℓp ). It is shown in [3] that c(S1 ) ≤ C(G)/h = 2 2C(G)/t. The removal of the vertices in S1 partitions G into subgraphs G0 , . . . , Gp , where G0 = G[V − (ℓ1 )], Gp = G[V + (ℓp )], and, for 0 < i < p, Gi = G[V + (ℓi ) ∩ V − (ℓi+1 )]; see Figure 6.1(a). 6.1.3
Partitioning the Layers
A subgraph Gi whose weight exceeds tw(G) is partitioned into subgraphs of size at most tw(G) using fundamental cycles w.r.t. a spanning tree Ti . The tree Ti is obtained as follows: If i > 0, a new vertex si of cost and weight 0 is added to Gi and made adjacent to all vertices of Gi that, in G, are adjacent to vertices in L(ℓi ). if i = 0, let s0 = s. Then Gi is triangulated, and Ti is computed as a shortest-path tree rooted in si . From the choice of levels L(ℓ1 ), . . . , L(ℓp ) it follows that r(Ti ) ≤ 2h, so that every fundamental i) cycle w.r.t. Ti has cost at most 4h. Below we argue that ⌊ 2w(G tw(G) ⌋ fundamental cycles suffice to partition Gi into subgraphs of weight at most tw(G), that is, Gi can be partition into subgraphs i) of weight at most tw(G) using a separator of cost at most 4h⌊ 2w(G tw(G) ⌋. Let S2 be the union of p P i) 8h/t = 2 2C(G)/t. these separators for all graphs G0 , . . . , Gp . Then c(S2 ) ≤ 4h pi=0 ⌊ 2w(G tw(G) ⌋ ≤ p Hence, the cost of the final separator S = S1 ∪ S2 is c(S) = c(S1 ) + c(S2 ) ≤ 4 2C(G)/t. Since S1 partitions G into graphs G0 , . . . , Gp and S2 partitions graphs G0 , . . . , Gp into subgraphs of weight at most tw(G), S is a t-separator. j k i) In order to compute 2w(G fundamental cycles that partition Gi into subgraphs of weight at tw(G) most tw(G), the idea of a separation tree is used, which has been introduced in [2]. The separation tree Di of Gi w.r.t. Ti is defined as follows: Let G∗i be the dual of Gi . Then Di is obtained from G∗i by removing all edges that are dual to edges in Ti . Any edge set X = {e∗1 , . . . , e∗k } of Di defines a set of fundamental cycles F(X) = {F (e1 ), . . . , F (ek )}. Next we present an assignment of weights to the edges of graph Di , proposed in [2], that ensures that the set F(Xi ) corresponding to a t′ -edge separator of Di is a t′ -vertex separator of Gi . Thus, it suffices to compute a t′ -edge separator Xi of Di , for t′ = tw(G)/w(Gi ), and add the vertices on the fundamental cycles in F(Xi ) to S2 . To compute the necessary assignment w∗ of weights to the edges of Di , we define two sets of edges for every vertex x ∈ Vi : The set E0 (x) contains all non-tree edges incident to x. The set E1 (x) contains all non-tree edges both of whose endpoints are adjacent to x. It is shown in [2] that E1 (x) 6= ∅, for all x ∈ Vi . Initially, let w∗ (e∗ ) = 0, for every edge e∗ ∈ Di . For every vertex x ∈ Vi with E0 (x) 6= ∅, choose an edge e ∈ E0 (x) and increase the weight w∗ (e∗ ) of its dual by w(x). For every vertex x ∈ Vi with E0 (x) = ∅, choose an edge e ∈ E1 (x) and increase the weight w∗ (e∗ ) of e∗ by w(x). Note that with this definition of edge weights w∗ (e∗ ), w∗ (Di ) = w(Gi ). It is shown in [2] that the set F(Xi ) of fundamental cycles defined by a t′ -edge separator Xi of Di w.r.t. these weights is a t′ -separator of Gi . Intuitively, F(Xi ) partitions the plane into regions, each corresponding to a subtree of Di − Xi . The weight of every vertex in such a region must have been charged to an edge in the corresponding subtree; but, since Xi is a t′ -separator of Di , no subtree has weight exceeding t′ w(Gi ); that is, the fundamental cycles in F(Xi ) form a t′ -vertex separator of Gi . By choosing t′ = tw(G)/w(Gi ), we obtain a partition of Gi into subgraphs of weight at most 28
tw(G). k j k j ∗ 2w(Gi ) (Di ) ′ = In order to compute a t′ -edge separator Xi of size at most 2w tw(G) tw(G) , for t = tw(G)/w(Gi ), the algorithm of [2] chooses a leaf of Di as the root and then processes Di bottomup. For every edge e∗ , let its tree weight be the weight of all edges in Di below e∗ , including e∗ itself. If the tree weight of e∗ exceeds tw(G)/2, edge e∗ is added to X. Edge e∗ and all edges below e∗ then do not contribute to the tree weights of edges above e∗ . It is easily verified that every subtree of Di − Xi has weight at most tw(G). Also, every edge added to Xi can be charged to the j ∗edgesk contributing to its tree weight. Their total weight is at least tw(G)/2, so that at most 2w (Di ) edges are added to Xi . tw(G) The computation of tree weights is easily implemented as follows: For an edge e∗ whose bottom endpoint is a leaf of Di , the tree weight of e∗ equals its weight. For any other edge e∗ , initialize the tree weight of e∗ to be equal to w∗ (e∗ ). When processing an edge f ∗ whose top endpoint is the same as the bottom endpoint of e∗ , add the tree weight of f ∗ to that of e∗ if f ∗ is not added to Xi . Otherwise, leave the tree weight of e∗ unchanged.
6.2
An I/O-Efficient Algorithm
Next we show that each step of the above algorithm can be carried out I/O-efficiently, thereby obtaining an I/O-efficient algorithm to compute a separator as in Theorem 6.1. 6.2.1
Computing T
ˆ of G can be computed in O(sort(N )) I/Os using the algorithm of [27]. In A planar embedding G [24], it is shown how to triangulate an embedded planar graph in O(sort(N )) I/Os. A representation of the faces of the resulting triangulation as lists of vertices on the boundary of each face can be computed in O(sort(N )) I/Os [24]. Given this representation, we scan one such list and make the new vertex s adjacent to all vertices in this list. It takes O(sort(N )) I/Os to label every edge of G with the costs of its endpoints, replace every edge of G with its corresponding directed edges, and assign weights as defined above to these edges (see Section 2.4). The shortest-path tree T can now be computed in O(sssp(N )) I/Os using the shortest-path algorithm of [8]. (This is where our weighted separator algorithm depends on the unweighted separator algorithm from Section 4 because the shortest-path algorithm of [8] requires a regular proper B 2 -partition to be given.) 6.2.2
Cutting T into Layers
Given the distances of the vertices of T from s, we compute values ℓ1 , . . . , ℓp , as defined in Section 6.1, as follows: First we label both endpoints of every edge with their costs and their distances from the root s of T . Then we sort the edges of T by the distances of their source vertices from s. We scan the sorted edge list to simulate a sweep from ℓ = −∞ to ℓ = +∞. During the sweep, we maintain the weight of the current set L(ℓ), the minimum cost cmin (i) found in the interval (ℓ′i−1 , ℓ′i ], and the value ℓi ∈ (ℓ′i−1 , ℓ′i ] such that c(L(ℓi )) = cmin (i). When ℓ = d(xj ), for some vertex xj , we perform the following operations: If d(xj+1 ) > ℓ′i , we report ℓi , increase i by one, and initialize cmin (i) = +∞. Then we decrease c(L(ℓ)) by c(xj ) and increase c(L(ℓ)) by the total cost of the target vertices of all edges having xj as a source vertex. This produces c(L(d(xj+1 ))). If c(L(d(xj+1 ))) < cmin (i), we update cmin (i) = c(L(d(xj+1 ))) and ℓi = d(xj+1 ).
29
Given values ℓ1 < · · · < ℓp and the edge set of T as sorted above, the set S1 = L(ℓ1 ) ∪ · · · ∪ L(ℓp ) can be extracted as follows: We scan the list of values ℓ1 , . . . , ℓp and the edge set of T , again to simulate a sweep from ℓ = −∞ to ℓ = +∞. When the sweep passes the source vertex of an edge e, we append edge e to a list L of edges that contains all edges spanning the current sweep value ℓ, but may contain more edges. When the sweep passes a value ℓi , we scan list L to add all target vertices of edges xy ∈ L with d(x) < ℓi ≤ d(y) to S1 . Then we set L = ∅. The reason for resetting L is that endpoints of edges that span two values ℓi and ℓi+1 should be reported only once, and endpoints of edges in L that have not been reported for ℓi cannot be reported for ℓi+1 because, for each such edge xy, d(y) < ℓi ≤ ℓi+1 . Since this phase requires sorting and scanning the edge set of T a constant number of times, its I/O-complexity is O(sort(N )). 6.2.3
Partitioning the Layers
This phase of the algorithm extracts graphs G0 , . . . , Gp , computes shortest-path trees T0 , . . . , Tp for these graphs, and partitions each graph Gi , 0 ≤ i ≤ p, into subgraphs of weight at most tw(G), using fundamental cycles of Ti . Computing the layers. We compute graphs G0 , . . . , Gp as follows: First we compute the set V − S1 and sort the vertices in V − S1 by their distances from s. We scan the vertices in V − S1 and the values 0 = ℓ0 , ℓ1 , . . . , ℓp , ℓp+1 = r(T ) to partition V − S1 into sets V0 , . . . , Vp , where Vi = {x ∈ V − S1 : ℓi < d(x) ≤ ℓi+1 }. For 1 ≤ i ≤ p, we add a new vertex si to Vi . This produces the vertex sets of graphs G0 , . . . , Gp . Next we partition E into sets E0 , . . . , Ep , E1− , . . . , Ep− , and E + such that every edge in Ei has both endpoints in Vi ; every edge xy in Ei− has one endpoint, say y, in Vi , and the other endpoint, x, satisfies x ∈ S1 and d(x) < d(y); and set E + contains the remaining edges. This partition is easily computed in O(sort(N )) I/Os: We label every edge with the membership of its endpoints in V0 , . . . , Vp or S1 and with their distances from s. Every edge can then determine its membership in one of the sets based on its local information, so that we can sort E to obtain the desired partition. Graph Gi is now defined as Gi = (Vi , Ei ∪ Ei′ ), where Ei′ = {si y, ysi : xy ∈ Ei− and d(x) < d(y)}. Finally, we triangulate Gi using the algorithm of [24]. This procedure requires sorting and scanning the vertex and edge sets of G a constant number of times. In addition, we invoke the O(sort(N ))-I/O triangulation algorithm of [24] on graphs G0 , . . . , Gp , whose total size is O(N ). Hence, the extraction of graphs G0 , . . . , Gp takes O(sort(N )) I/Os. Computing the separation trees. To compute the separation tree Di for each graph Gi , we start by computing a shortest-path tree Ti of Gi rooted in si and then extract Di . Using the separator algorithm from Section 4 and the shortest-path algorithm of [8], the construction of Ti takes O(sssp(|Gi |)) I/Os. To construct Di , we compute the dual G∗i = (Fi , Ei∗ ) of Gi , which can be done in O(sort(|Gi |)) I/Os using an algorithm from [24]. Then we remove all edges dual to edges in Ti from Ei∗ . This takes another O(sort(|Gi |)) I/Os (see Section 2.4). Thus, in total, the construction of all separation trees D0 , . . . , Dp takes O(sssp(N )) I/Os. Computing dual edge weights. Before computing an edge separator of Di and the corresponding set of fundamental cycles, we have to assign weights to the edges of Di , as defined in
30
Section 6.1.3. We do this in two phases. The first one partitions Vi into two sets Vi0 and Vi1 such that E0 (x) 6= ∅ for all x ∈ Vi0 and E0 (x) = ∅ for all x ∈ Vi1 . It also identifies an edge e ∈ E0 (x) for every vertex x ∈ Vi0 and adds w(x) to the weight w∗ (e∗ ) of e’s dual. The second phase finds an edge e ∈ E1 (x) for every x ∈ Vi1 and adds w(x) to w∗ (e∗ ). The details are as follows: To implement Phase 1, we create a list Yi of non-tree edges of Gi . More precisely, Yi contains directed edges xy and yx for every non-tree edge xy of Gi . We sort the edges in Yi by their source vertices and the vertices in Vi by their IDs. List Yi is now the concatenation of lists E0 (x), for all x ∈ Vi0 , and a single scan of lists Vi and Yi suffices to partition Vi into Vi0 and Vi1 and add a pair (e∗ , w(x)) to a list W , for every vertex x ∈ Vi0 and the first edge e ∈ E0 (x). List W will be used after Phase 2 to add w(x) to w∗ (e∗ ) for all entries (e∗ , w(x)) ∈ W . To implement Phase 2, we observe that, for every edge yz such that y and z are neighbours of x in Ti , one endpoint, say y, must be a child of x in Ti , and the other, z, must be x’s parent in Ti or another child of x. Therefore, we can compute sets E1 (x), for all x ∈ Ti , as follows: First we label every vertex x ∈ Ti with its grandparent in Ti . This can be done by creating two copies of Vi , sorting one by vertex IDs, the other by parent IDs, and then scanning the two lists. Now we label every non-tree edge of Gi with the parents and grandparents of its endpoints. For every non-tee edge yz, yz ∈ E1 (x) if and only if p(y) = p(z) = x or, w.l.o.g., p(y) = x and z = p(x) = p(p(y)). This can be tested based on the local information stored with edge yz. If edge yz satisfies this condition, we give it E1 -label x. Otherwise, it receives E1 -label nil. We sort the non-tree edges by their E1 -labels and scan Vi1 and the sorted edge list to add a pair (e∗ , w(x)) to W , for every vertex x ∈ Vi1 and the first edge e ∈ E1 (x). Finally, we sort the edges of Di by their IDs and the pairs in W by their first components. A single scan of these two sorted lists suffices to add w(x) to w∗ (e∗ ), for every pair (e∗ , w(x)) ∈ W . Since this procedure sorts and scans lists of size O(|Gi |) a constant number of times, the assignment of weights to the edges of Di takes O(sort(|Gi |)) I/Os. The total cost for all graphs G0 , . . . , Gp is therefore O(sort(N )). Computing the edge separator and fundamental cycles. To obtain the edge separator Xi of Di , we root Di at an arbitrary leaf, compute a preorder numbering of Di w.r.t. the chosen root, and direct all edges in Di from children to parents. This can be done using the Euler tour technique and list ranking [14]. Then we use time-forward processing [14] to carry out the procedure of [2] for partitioning Qi into subgraphs of weight at most tw(G) (see the end of Section 6.1.3). Given the edge separator Xi of Di produced by this procedure, we mark the endpoints of all edges e ∈ Gi such that e∗ ∈ Xi . Now we process Ti bottom-up (using time-forward processing again) to identify all vertices of Gi that belong to the fundamental cycles defined by the edges in Xi . We add these vertices to S2 . As applying the Euler-tour technique, list-ranking, and time-forward processing to Di take O(sort(|Di |)) = O(sort(|Gi |)) I/Os, the computation of the edge separator Xi takes O(sort(|Gi |)) I/Os. The marking of the endpoints of edges that are dual to edges in Xi takes O(sort(|Gi |)) I/Os. The final application of time-forward processing to extract the vertex set of the fundamental cycles in F(Xi ) takes another O(sort(|Gi |)) I/Os. Hence, the total cost of this last phase of the computation of S2 is O(sort(N )). Since we have shown that the computation of both S1 and S2 can be carried out in O(sssp(N )) I/Os, we obtain
31
Theorem 6.2 Given a planar graph G = (V, E), a cost function c : V → R+ , and a weight function w : V → R+ , a separator S as in Theorem 6.1 can be computed in O(sssp(N )) I/Os, provided that M = Ω(B 2 log2 B). The memory requirements of the algorithm are inherited from the separator algorithm of Section 4 and the shortest-path algorithm of [8]. In particular, the latter requires a proper Θ(B 2 )partition as part of the input and uses Θ(B 2 ) main memory to carry out its computation. The algorithm from Section 4 can be used to produce the desired partition in O(sort(N )) I/Os, provided that M = Ω(B 2 log2 B). Actually, things are a little more complicated: Graph G, once triangulated, is not necessarily of bounded degree and, thus, does not necessarily have a regular proper Θ(B 2 )-partition, but this is what the shortest-path algorithm of [8] requires. If G is embedded, this problem can be solved by applying the following standard transformation to obtain a graph G′ of degree at most three and of size O(N ) from G: For every vertex v with deg(v) = k > 3, let w1 , . . . , wk be the neighbours of v, clockwise around v. Then replace v with a directed cycle (v1 , . . . , vk ), replace edges vwi and wi v with edges vi wi and wi vi of the same weight, and assign weight 0 to every edge vi vi+1 and vk v1 . Then distG (v, w) = distG′ (vi , wj ), for any two vertices v and w of G and any two indices 1 ≤ i ≤ deg(v) and 1 ≤ j ≤ deg(w). Thus, we can compute shortest paths in G by computing shortest paths in G′ . Using the algorithm from Section 5, we can obtain a regular proper Θ(B 2 )partition of G′ , and then we use the shortest-path algorithm of [8] to compute shortest paths in G′ . Since |G′ | = O(N ), this affects the complexity of the algorithm by only a constant factor. The planar embedding required to perform this transformation can be computed in O(sort(N )) I/Os using the embedding algorithm in the companion paper [27].
6.3
Edge Separators
The final result of this section is an I/O-efficient edge separator algorithm, which is an immediate consequence of Theorem 6.2. It is shown in [3] that Theorem 6.1 can also be used to compute optimal weighted edge separators of planar graphs: Let the cost of a vertex be equal to its degree. Then compute a vertex separator S of low cost. For every vertex x ∈ S, add all edges incident to x to the edge separator X. It is easy to verify that the computation of the vertex costs and the extraction of set X from set S can be carried out in O(sort(N )) I/Os. Hence, we obtain Theorem 6.3 Let G = (V, E) be a planar graph, let 0 < t < 1 be a real number, and let w : V → R+ beqa weight function so that w(x) ≤ tw(G), for all x ∈ V . Then there exists a set X of at most P 2 4 2 v∈V (deg(v)) /t edges so that no connected component of G − X has weight exceeding
tw(G). Such an edge separator X can be found in O(sssp(N )) I/Os, provided that M ≥ B 2 log2 B.
7
Improving the Memory Requirements
In this final section of the paper, we argue how to reduce the memory requirements of our algorithm from Section 4 to M ≥ max(196B 2 , r). The resulting algorithm also produces a separator significantly smaller than the one produced by the algorithm in Section 4. However, these two improvements come at the expense of increasing the complexity of the algorithm from O(sort(N )) to O(sssp(N )); that is, the I/O-complexity increases by only a constant factor, but the internalmemory computation increases significantly. 32
Recall the reason why M ≥ 56r log2 B is required for the algorithm in Section 4: If we choose to compute an r ′ -partition of each√graph Gi in the hierarchy, then the separator vertices introduced at each level correspond to O(N/ r ′ ) vertices in G; no better upper bound is known. Since there √ are ⌊log B⌋ √ levels in the hierarchy, and we want a separator of size O(N/ r), we have to ensure √ that O((N/ r ′ ) log B) = O(N/ r), which we achieve by choosing r ′ = r log2 B. This now forces us to use 56r log2 B main memory because, as argued in Section 4, every piece of Gi − Si′ has size at most 56r log2 B, and we need to load each such piece into memory to partition it into smaller pieces. So the central problem is that, if we were to choose r ′ = r, then every level in the hierarchy √ adds O(N/ r) vertices to the final separator of G, that is, we would obtain a separator that is by a factor log B too big. Next we explain how to avoid this problem by using a recursive bootstrapping approach. The centerpiece of the algorithm is the separator algorithm from Section 6, now using vertex costs and weights equal to 1. This algorithm takes O(sort(N )) I/Os using only Θ(B) main memory, if we ignore the costs and memory requirements of computing an embedding of G, computing the shortest-path tree T of G, and computing the shortest-path trees T0 , . . . , Tp for the different layers G0 , . . . , Gp . Given appropriate separator decompositions, the computation of the embedding and the shortestpath computations take O(sssp(N )) I/Os and require Θ(B 2 ) main memory. Our strategy is to obtain these separator decompositions by recursive application of the separator algorithm. Embedding G and computing T . To compute a planar embedding of G, we require a normal Θ(B 2 )-partition P = (S, {G1 , . . . , Gp }) of G. We obtain this partition by applying the uniform graph contraction procedure to G, recursively computing a normal B 2 -partition P˜ = ˜ {G ˜1 , . . . , G ˜ p }) of the resulting graph G, ˜ and then choosing S to be the set of vertices in (S, ˜ To obtain G ˜ from G, we assign weight 1 to every verG represented by the vertices in S. tex in G and choose a weight threshold u, to be specified later, in the uniform graph contrac2 ˜ ˜ tion Pp |S| ≤˜ u|S| = O(N/B), |Gi | ≤ u|Gi | = O(B 2 ), for all 1 ≤ i ≤ p, and Pp procedure. Then i=1 |N (Gi )| ≤ u i=1 |N (Gi )| = O(N/B). Thus, P is a normal Θ(B )-partition of G. Given a planar embedding of G, we can now construct the degree-3 graph G′ from G. We apply the procedure we have just described to obtain a normal Θ(B 2 )-partition for G′ . Using the procedures from Sections 4.3 and 5, this partition can be augmented to obtain a regular proper B 2 -partition of G′ , which we then use to compute the shortest-path tree T . Computing T0 , . . . , Tp. In order to compute shortest-path trees T0 , . . . , Tp , we apply the same procedure as above to each graph Gi , except that Gi is already embedded. Hence, we only have to compute a regular proper B 2 -partition of G′i , in order to compute Ti . Putting it all together. To bound the cost of our recursive procedure, we first bound the sizes of the different graphs involved in the computation: Graph G has N vertices. Graph G′ has at most 6N vertices, at most two per edge in G. Graphs G0 , . . . , Gp contain at most N vertices. Thus, graphs G′0 , . . . , G′p contain at most 6N vertices. The total size of graphs G, G′ , G0 , . . . , Gp , G′0 , . . . G′p is therefore O(N ). This implies that all steps of the algorithm, excluding the recursive computation of ˜ G ˜′, G ˜′ , . . . , G ˜ ′ , take O(sssp(N )) I/Os and require uB 2 = Θ(B 2 ) proper B 2 -partitions for graphs G, p 1
33
main memory, that is, the cost of the algorithm is given by the recurrence ˜ + T (|G ˜ ′ |) + T (N ) = O(sssp(N )) + T (|G|)
p X i=0
˜ ′i |). T (|G
˜ contains at most |G|/98 heavy vertices and, by Lemma 3.1, has size If we choose u = 196, graph G ˜ ˜ ′ | ≤ |G′ |/14. Thus, we have at most |G|/14. Similarly, |G′ | ≤ |G′ |/14 and, for 0 ≤ i ≤ p, |G i i ˜ + |G ˜′| + |G|
p X i=0
p
˜ ′i | ≤ |G
|G| |G′ | X |G′i | + + 14 14 14 i=0
6N 6N N + + 14 14 14 13N , = 14 and the recurrence solves to T (N ) = O(sssp(N )). This proves that we can compute a t-vertex separator and, thus, a t-edge separator, for any 0 < t < 1, in O(sssp(N )) I/Os, provided that M ≥ 196B 2 . In order to obtain a (regular) proper r-partition from an (r/N )-separator, we still have to be able to load subgraphs of size O(r) into internal memory, that is, we cannot do with less than r main memory. This proves the following result. ≤
Theorem 7.1 The partitions in Theorems 4.1 and 5.1 can be computed in O(sssp(N )) I/Os, provided that M ≥ max(196B 2 , r). The separators in Theorems 6.2 and 6.3 can be computed in O(sssp(N )) I/Os, provided that M ≥ 196B 2 .
The memory requirements in Theorem 7.1 can be reduced further to M ≥ max(cB 2 , r) and M ≥ cB 2 , for an arbitrarily small constant c > 0. Indeed, 196B 2 memory is required because we recursively compute B 2 -partitions of the compressed graphs, which correspond to 196B 2 -partitions in the uncompressed graphs. Instead, we can compute cB 2 /196-partitions of the compressed graphs, thereby obtaining cB 2 -partitions of the uncompressed graphs. This affects the size of the produced separators and, thus, the performance of the embedding and shortest-path algorithms by only a constant factor, but reduces the memory requirements.
8
Conclusions
In this paper, we have demonstrated that different types of separator decompositions of planar graphs can be computed I/O-efficiently. Using these partitions, a wide variety of fundamental problems on planar graphs can be solved I/O-efficiently. A number of open questions remain, however. First of all, the constant factors in our algorithms— in terms of the size of the produced separator, the memory requirements, and the efficiency—are big. In order for the algorithms to be of practical value, these constant factors have to be reduced. Even though the individual steps of the algorithm are fairly simple, the algorithm consists of too many of them. This impacts the efficiency of the algorithm—for example, only a small number of sorting steps are affordable in practice—and makes the algorithm tedious to implement. From a practical point of view, it would therefore be desirable to have a simpler, even possibly theoretically suboptimal algorithm for computing separators I/O-efficiently. On the theoretical side, the most important open question is whether separators can be computed in O(sort(N )) I/Os using o(B 2 ) main memory. 34
References [1] A. Aggarwal and J. S. Vitter. The input/output complexity of sorting and related problems. Communications of the ACM, pages 1116–1127, September 1988. [2] L. Aleksandrov and H. Djidjev. Linear algorithms for partitioning embedded graphs of bounded genus. SIAM Journal of Discrete Mathematics, 9:129–150, 1996. [3] L. Aleksandrov, H. Djidjev, H. Guo, and A. Maheshwari. Partitioning planar graphs with costs and weights. In Proceedings of the 4th Workshop on Algorithm Engineering and Experiments, volume 2409 of Lecture Notes in Computer Science, pages 98–107. Springer-Verlag, 2002. [4] L. Arge. The buffer tree: A technique for designing batched external data structures. Algorithmica, 37(1):1–24, 2003. [5] L. Arge, G. S. Brodal, and L. Toma. On external-memory MST, SSSP and multi-way planar graph separation. Journal of Algorithms, 53(2):186–206, 2004. [6] L. Arge, U. Meyer, L. Toma, and N. Zeh. On external-memory planar depth first search. Journal of Graph Algorithms and Applications, 7(2):105–129, 2003. [7] L. Arge and L. Toma. Simplified external memory algorithms for planar DAGs. In Proceedings of the 9th Scandinavian Workshop on Algorithm Theory, volume 3111 of Lecture Notes in Computer Science, pages 493–503. Springer-Verlag, 2004. [8] L. Arge, L. Toma, and N. Zeh. I/O-efficient algorithms for planar digraphs. In Proceedings of the 15th ACM Symposium on Parallelism in Algorithms and Architectures, pages 85–93, 2003. [9] L. Arge and N. Zeh. I/O-efficient strong connectivity and depth-first search for directed planar graphs. In Proceedings of the 44th IEEE Symposium on Foundations of Computer Science, pages 261–270, 2003. [10] K. Booth and G. Lueker. Testing for the consecutive ones property, interval graphs, and graph planarity using PQ-treealgorithms. Journal of Computer and System Sciences, 13:335–379, 1976. [11] J. Boyer and W. Myrvold. Stop minding your P’s and Q’s: A simplified O(n) planar embedding algorithm. In Proceedings of the 10th Annual ACM-SIAM Symposium on Discrete Algorithms, pages 140–146, 1999. [12] A. Broder, R. Kumar, F. Manghoul, P. Raghavan, S. Rajagopalan, R. S. andA. Tomkins, and J. Wiener. Graph structure in the web. In Proceedings of the 9th International World-Wide Web Conference, 2000. http://www9.org. [13] A. L. Buchsbaum and J. R. Westbrook. Maintaining hierarchical graph views. In Proceedings of the Annual ACM-SIAM Symposium on Discrete Algorithms, pages 566–575, 2000. [14] Y.-J. Chiang, M. T. Goodrich, E. F. Grove, R. Tamassia, D. E. Vengroff, and J. S. Vitter. External-memory graph algorithms. In Proceedings of the 6th Annual ACM-SIAM Symposium on Discrete Algorithms, pages 139–149, January 1995. 35
[15] K. Diks, H. N. Djidjev, O. Sykora, and I. Vrto. Edge separators of planar and outerplanar graphs with applications. Journal of Algorithms, 14:258–279, 1993. [16] H. N. Djidjev. Partitioning graphs with costs and weights on vertices: Algorithms and applications. Algorithmica, 28:51–75, 2000. [17] H. N. Djidjev and J. R. Gilbert. Separators in graphs with negative and multiple vertex weights. Algorithmica, 23:57–71, 1999. [18] S. Even and R. E. Tarjan. Computing an st-numbering. Theoretical Computer Science, 2:339– 344, 1976. [19] G. N. Frederickson. Fast algorithms for shortest paths in planar graphs, with applications. SIAM Journal on Computing, 16(6):1004–1022, December 1987. [20] J. R. Gilbert, J. P. Hutchinson, and R. E. Tarjan. A separator theorem for graphs of bounded genus. Journal of Algorithms, 5:391–407, 1984. [21] M. T. Goodrich. Planar separators and parallel polygon triangulation. Journal of Computer and System Sciences, 51(3):374–389, 1995. [22] F. Harary. Graph Theory. Addison-Wesley, 1969. [23] J. Hopcroft and R. E. Tarjan. Efficient planarity testing. Journal of the ACM, 21(4):549–568, 1974. [24] D. Hutchinson, A. Maheshwari, and N. Zeh. An external memory data structure for shortest path queries. Discrete Applied Mathematics, 126:55–82, 2003. [25] A. Lempel, S. Even, and I. Cederbaum. An algorithm for planarity testing of graphs. In Theory of Graphs: International Symposium (Rome 1966), pages 215–232, New York, 1967. Gordon and Breach. [26] R. J. Lipton and R. E. Tarjan. A separator theorem for planar graphs. SIAM Journal on Applied Mathematics, 36(2):177–189, 1979. [27] A. Maheshwari and N. Zeh. I/O-efficient algorithms for planar graphs II: Planarity testing and planar embedding. SIAM Journal on Computing, 2004. Submitted. [28] U. Meyer, P. Sanders, and J. Sibeyn, editors. Algorithms for Memory Hierarchies: Advanced Lectures, volume 2625 of Lecture Notes in Computer Science. Springer-Verlag, 2003. [29] G. L. Miller. Finding small simple cycle separators for 2-connected planar graphs. Journal of Computer and System Sciences, 32:265–279, 1986. [30] K. Munagala and A. Ranade. I/O-complexity of graph algorithms. In Proceedings of the 10th Annual ACM-SIAM Symposium on Discrete Algorithms, pages 687–694, January 1999. [31] W. T. Tutte. Graph Theory. Cambridge University Press, 2001. First published by AddisonWesley, 1984.
36
[32] J. S. Vitter. External memory algorithms and data structures: Dealing with massive data. ACM Computing Surveys, 33(2):209–271, 2001. [33] N. Zeh. I/O-Efficient Algorithms for Shortest Path Related Problems. PhD thesis, School of Computer Science, Carleton University, 2002.
37