Simple, Linear-Time Modular Decomposition
Total Page:16
File Type:pdf, Size:1020Kb
Simple, Linear-time Modular Decomposition (Extended Abstract)∗ Marc Tedder,1 Derek Corneil,1 Michel Habib,2 Christophe Paul3 Abstract Modular decomposition is fundamental for many important problems in algorithmic graph theory including transitive orientation, the recognition of several classes of graphs, and certain combinatorial optimization problems. Accordingly, there has been a drive towards a practical, linear-time algorithm for the problem. Despite considerable effort, such an algorithm has re- mained elusive. The linear-time algorithms to date are impractical and of mainly theoretical interest. In this paper we present the first simple, linear-time algorithm to compute the modular decomposition tree of an undirected graph. 1 Introduction A natural operation to perform on a graph G is to take one of its vertices, say v, and replace it with another graph G′, making v’s neighbours universal to the vertices of G′. Modular decomposition is interested in the inverse operation: finding a set of vertices sharing the same neighbours outside the set – that is, finding a module – and contracting this module into a single vertex. A graph’s modules form a partitive family [2], and as such, define a decomposition scheme for the graph with an associated decomposition tree composed of the graph’s strong modules – those that don’t overlap other modules. To compute this modular decomposition tree is to compute the modular decomposition (and vice versa); and with its succinct representation of a graph’s structure, its computation is often a first-step in many algorithms. Indeed, since Gallai first noticed its importance to comparability graphs [11], modular decomposition has been established as a fundamental tool in algorithmic graph arXiv:0710.3901v2 [cs.DM] 20 Mar 2008 theory. All efficient transitive orientation algorithms make essential use of modular decomposition (e.g., [17]). It is frequently employed in recognizing different families of graphs, including interval graphs [18], permutation graphs [24], and cographs [3]. Furthermore, restricted versions of many ∗ Marc Tedder and Derek Corneil thank NSERC of Canada for partially funding this research; Michel Habib and Christophe Paul received funding from the French ANR project “Graph Decomposition and Algorithms” (GRAAL). 1Department of Computer Science, University of Toronto; {mtedder,dgc}@cs.toronto.edu 2LIAFA and the University of Paris 7 - Denis Diderot; [email protected] 3CNRS - LIRMM, Univ. Montpellier II France; [email protected]; part of this research was conducted while on sabbatical in the School of Computer Science at the University of McGill, Montr´eal, Canada. 1 combinatorial optimization problems can be efficiently solved using modular decomposition (e.g., [8]). While the papers [18, 19, 20] provide older surveys of its numerous applications, new uses continue to be found, such as in the areas of graph drawing [23] and bioinformatics [10]. Not surprisingly, the problem of computing the modular decomposition has received considerable attention. Much like planarity testing and interval graph recognition, the importance of the problem has bent efforts toward a simple and efficient solution. The first polynomial-time algorithm appeared in the early 1970’s and ran in time O(n4) [5]. Incremental improvements were made over the years – [13, 21], for example – culminating in 1994 with the first linear-time algorithms, developed inde- pendently by McConnell and Spinrad [16], and Cournier and Habib [4]. These are unfortunately so complex as to be viewed primarily as theoretical contributions, with Spinrad himself hoping they would be supplanted by something simpler (pg. 149, [25]). Subsequent algorithms, though, have fallen short, either failing to achieve linear-time or appealing to sophisticated data-structure tech- niques in doing so. The attempts made by [17] and [7] are illustrative. Both adopt an approach pioneered by Ehren- feucht et. al. [9], later improved upon by Dahlhaus [6]. The idea is to pick an arbitrary vertex, say x, and recursively compute the modular decomposition tree for its neighbourhood, N(x), and its non-neighbourhood, N(x). Any strong module not containing x must be a module of either G[N(x)] or G[N(x)], and therefore can be extracted from their recursively computed modular decomposition trees. Once extracted, these can then be used to compute the strong modules containing x. The two types of modules are then assembled to form the tree. Although this approach is conceptually simple, [17] only managed an O(n + m log n) implementation, while [7] required advanced union-find data structures and complicated charging arguments to achieve linear-time. The difficult step in the recursive approach is the computation of the strong modules containing x and their incorporation into the tree; in other words, the explicit construction of the tree. Capelle and Habib [1] responded by proposing the use of factorizing permutations, a permutation of the vertices in which the strong modules appear consecutively. They suggested that a factorizing permutation be computed in place of the tree; if the tree is required it can be derived from the permutation once, at the end of the algorithm, using the linear-time procedure in [1]. But how to compute the permutation? The linear-time algorithm claimed in [12] contains an error that kills its simplicity, and the algorithm of [15] has a log n-factor. It seemed factorizing permutations merely traded one bottleneck for another. The real problem with the two approaches is that they were applied in isolation. This paper shows that the two are truly complementary: the recursively computed trees facilitate the computation of a factorizing permutation, which in turn facilitates the computation of the modular decomposition tree. By unifying the approaches in this way we produce an elegant, linear-time algorithm for the modular decomposition, thus realizing a long-standing goal in the area. We combine the best aspects of the two methods, maintaining the conceptual simplicity of both. This allows a straightforward proof of correctness. The only data-structure employed is an ordered list of trees, and on these, only elementary traversals are required. Moreover, to produce the factorizing permutation from the recursively computed trees, we introduce a procedure that generalizes partition refinement [22] from sets to trees. This and other ideas we develop here can also be applied to the transitive 2 orientation problem: the authors are confident of having developed the first simple, linear-time transitive orientation algorithm by doing just this [26]. 1.1 Preliminaries All graphs in this paper are simple and undirected. Connected components will simply be referred to as components, while the connected components of the complement will be referred to as co- components. We will talk often of an ordered list of trees, which will sometimes be referred to as an ordered forest. When we speak of them as defining an ordering of the graph’s vertices, we mean a pre-ordering of the leaves of each tree in order. Note that sometimes a set of vertices will be referred to as a “tree”. We do this to streamline the exposition; our intent will become clear. The modular decomposition tree will occasionally be referred to as the MD tree. The MD tree can be recursively defined as follows: the root of the tree corresponds to the entire graph; if the graph is disconnected, the root is called parallel and its children are the MD trees of its components; if the graph’s complement is disconnected, the root is called series and its children are the MD trees of the co-components; in all other cases the root is called prime4, and its children are the MD trees of the graph’s maximal modules. Recall that the nodes in this tree are the graph’s strong modules, which are those that don’t overlap others. 1.2 Outline of the Paper The rest of the paper breaks down into four sections. The first provides an overview of the algorithm, explaining its operation and how this contributes to its correctness and the ultimate construction of the MD tree. In the next section we specify the algorithm in detail and sketch the proof of its correctness. An analysis of the algorithm’s running time follows. The paper concludes with a discussion of our contributions. The appendix contains an example and some omitted proofs. 2 Overview of the Algorithm 2.1 Recursion The algorithm begins in a familiar way, selecting an arbitrary vertex, x, called the pivot, and placing its neighbourhood to its left and its non-neighbourhood to its right, giving us the ordered list of trees, N(x), x, N(x). Next, the modular decomposition tree for G[N(x)] is recursively computed. As this occurs, the neighbours of N(x) in N(x) are “pulled forward” so that afterwards we have the ordered list of trees, T (N(x)), x, NA(x), NN (x), where T (N(x)) is the modular decomposition tree for G[N(x)], and NA(x) is the subset of N(x) with at least one neighbour in N(x). The algorithm then recursively computes the modular decomposition tree for NA(x), pulling its neighbours in NN (x) forward in a similar fashion. And so on. Eventually we arrive at the following ordered list of trees: 4This definition of prime differs somewhat from that which normally appears in the literature. 3 T (N ),x,T (N ),...,T (N ), (1) | {z0} | 1 {z k} N(x) N(x) where the Ni’s correspond to the distance layers in a breadth-first-search begun from x, and the T (Ni)’s are their modular decomposition trees. The rest of this paper assumes that the graph is connected and thus each vertex in Ni has an edge to Ni−1 (or x in the case of N0). When the graph is disconnected, the Ni’s up to Nk−1 along with x form one of its connected components.