From 6e832b0a77ed3aaabf0046fe0081c305856379d4 Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Sat, 13 Sep 2008 16:25:21 +0200 Subject: [PATCH] Removed files that are not needed for the saga itself. --- Makefile | 14 +- abscover.tex | 205 ------- abstract.tex | 1408 --------------------------------------------- programs/n0.c | 156 ----- pubs.tex | 113 ---- slides/Makefile | 7 - slides/brum2.png | Bin 101760 -> 0 bytes slides/slides.tex | 364 ------------ 8 files changed, 1 insertion(+), 2266 deletions(-) delete mode 100644 abscover.tex delete mode 100644 abstract.tex delete mode 100644 programs/n0.c delete mode 100644 pubs.tex delete mode 100644 slides/Makefile delete mode 100644 slides/brum2.png delete mode 100644 slides/slides.tex diff --git a/Makefile b/Makefile index 89f0c42..cbd8ba1 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -all: saga.ps abstract.ps abscover.ps pubs.ps +all: saga.ps CHAPTERS=cover pref mst ram adv opt dyn appl rank epilog notation @@ -8,12 +8,6 @@ CHAPTERS=cover pref mst ram adv opt dyn appl rank epilog notation tex $< && mv $*.toc $*.tok tex $< && mv $*.toc $*.tok -pubs.dvi: pubs.tex macros.tex fonts12.tex - tex $< - -abscover.dvi: abscover.tex - csplain $< - saga.dvi: $(addsuffix .tex,$(CHAPTERS)) %.ps: %.dvi @@ -28,10 +22,4 @@ mostlyclean: clean: mostlyclean rm -f *.ps *.pdf -countrefs: saga.dvi - grep -c bibitem saga.bbl - -upload: saga.pdf - scp -C saga.pdf jw:www/papers/saga/ - .SECONDARY: diff --git a/abscover.tex b/abscover.tex deleted file mode 100644 index 2915681..0000000 --- a/abscover.tex +++ /dev/null @@ -1,205 +0,0 @@ -% Cover of the abstract - -\input macros.tex -\input fonts12.tex - -\finaltrue -\hwobble=0mm -\advance\hsize by 1cm -\advance\vsize by 20pt - -\nopagenumbers -\parindent=0pt - -%%% Title page %%% - -{ - -\vglue 0.7in - -\font\ft=cmr17 -\font\xt=cmb17 at 24pt -\font\yt=cmti17 -\font\ct=cmsy17 at 18pt -\font\st=cmcsc17 at 20pt -\ft -\baselineskip=24pt - -\centerline{Charles University in Prague} -\centerline{Faculty of Mathematics and Physics} - -\vfil -\vfil - -\centerline{\epsfxsize=0.4\hsize\epsfbox{pic/mfflogo.eps}} - -\vfil -\vfil - -\centerline{\st Abstract of Doctoral Thesis} - -\vfil - -\centerline{\xt Graph Algorithms} - -\vfil -\vfil - -\centerline{\yt {\ct M}\kern-0.13em artin {\ct M}\kern-0.13em are\v{s}} - -\vfil - -\centerline{Department of Applied Mathematics} -\centerline{Malostransk\'e n\'am.~25} -\centerline{Prague, Czech Republic} - -\vfil - -\centerline{Supervisor: Prof.~RNDr.~Jaroslav Ne\v{s}et\v{r}il, DrSc.} -\centerline{Branch I4: Discrete Models and Algorithms} - -\vfil - -\centerline{2008} - -\vskip 0.5in -\eject - -\vglue 0pt -\eject -\vglue 0.7in - -\centerline{Univerzita Karlova v Praze} -\centerline{Matematicko-fyzik\'aln\'\i{} fakulta} - -\vfil -\vfil - -\centerline{\epsfxsize=0.4\hsize\epsfbox{pic/mfflogo.eps}} - -\vfil -\vfil - -\centerline{\st Autorefer\'at} - -\vfil - -\centerline{\xt Grafov\'e algoritmy} - -\vfil -\vfil - -\centerline{\yt {\ct M}\kern-0.13em artin {\ct M}\kern-0.13em are\v{s}} - -\vfil - -\centerline{Katedra aplikovan\'e matematiky} -\centerline{Malostransk\'e n\'am.~25} -\centerline{118 00~~Praha 1} - -\vfil - -\centerline{\v{S}kolitel: Prof.~RNDr.~Jaroslav Ne\v{s}et\v{r}il, DrSc.} -\centerline{Obor I4: Diskr\'etn\'\i{} modely a algoritmy} - -\vfil - -\centerline{2008} -\vskip 0.5in -\eject - -} - -%%% Subtitle page %%% - -{ -\vglue 0pt - -\language=\czech -\chyph -\font\ft=csr12 -\font\fb=csbx12 -\ft -\parskip=0pt - -Disertaèní práce byla vypracována v~rámci interního a navazujícího externího -doktorského studia na~Katedøe aplikované matematiky Matematicko-fyzikální fakulty -Univerzity Karlovy v~Praze. - -\bigskip - -{\fb Uchazeè:} Mgr. Martin Mare¹ - -\bigskip - -{\fb ©kolitel:} Prof.~RNDr.~Jaroslav Ne¹etøil, DrSc. - -\bigskip - -{\fb ©kolící pracovi¹tì:} - -\smallskip - -{\obeylines -Katedra aplikované matematiky -MFF UK -Malostranské nám. 25 -118 00 Praha 1 -} - -\bigskip - -{\fb Oponenti:} - -\smallskip - -{\obeylines - -Josep Díaz -Departament de Llenguatges i Sistemes Inform\`atics -Universitat Polit\`ecnica de Catalunya -Campus Nord -- Ed. Omega, 240 -Jordi Girona Salgado, 1--3 -E-08034 Barcelona, Spain - -\medskip - -Doc. RNDr. Václav Koubek, DrSc. -Katedra teoretické informatiky a matematické logiky -MFF UK -Malostranské nám. 25 -118 00 Praha 1 - -\medskip - -Patrice Ossona de Mendez -École de Hautes Études en Sciences Sociales -CAMS -- UMR 8557 -54 Boulevard Raspail -75006 Paris, France - -} - -\bigskip - -{\fb Pøedseda oborové rady I4:} Prof. RNDr. Jaroslav Ne¹etøil, DrSc. - -\bigskip - -Autoreferát byl rozeslán dne 27. 6. 2008. - -\medskip - -Obhajoba disertaèní práce se koná dne 29. 7. 2008 od 14:30 pøed komisí obhajoby -doktorských disertaèních prací v~oboru I4 v~budovì MFF UK na~Malostranském námìstí 25, -118 00 Praha 1. - -\medskip - -S~disertaèní prací je mo¾no se seznámit na~studijním oddìlení doktorského studia MFF UK, -Ke~Karlovu~3, 121 16 Praha 2. - -\vfill\eject -} - -\bye diff --git a/abstract.tex b/abstract.tex deleted file mode 100644 index 7c67936..0000000 --- a/abstract.tex +++ /dev/null @@ -1,1408 +0,0 @@ -\input macros.tex -\input fonts10.tex - -\finaltrue -\hwobble=0mm -\advance\hsize by 1cm -\advance\vsize by 20pt - -\def\rawchapter#1{\vensure{0.5in}\bigskip\goodbreak -\leftline{\chapfont #1} -} - -\def\rawsection#1{\medskip\smallskip -\leftline{\secfont #1} -\nobreak -\smallskip -\nobreak -} - -\def\schapter#1{\chapter{#1}\medskip} - -\schapter{Introduction} - -This thesis tells the story of two well-established problems of algorithmic -graph theory: the minimum spanning trees and ranks of permutations. At distance, -both problems seem to be simple, boring and already solved, because we have poly\-nom\-ial-time -algorithms for them since ages. But when we come closer and seek algorithms that -are really efficient, the problems twirl and twist and withstand many a~brave -attempt at the optimum solution. They also reveal a~vast and diverse landscape -of a~deep and beautiful theory. Still closer, this landscape turns out to be interwoven -with the intricate details of various models of computation and even of arithmetics -itself. - -We have tried to cover all known important results on both problems and unite them -in a~single coherent theory. At many places, we have attempted to contribute our own -little stones to this mosaic: several new results, simplifications of existing -ones, and last, but not least filling in important details where the original -authors have missed some. - -When compared with the earlier surveys on the minimum spanning trees, most -notably Graham and Hell \cite{graham:msthistory} and Eisner \cite{eisner:tutorial}, -this work adds many of the recent advances, the dynamic algorithms and -also the relationship with computational models. No previous work covering -the ranking problems in their entirety is known. - -We~have tried to stick to the usual notation except where it was too inconvenient. -Most symbols are defined at the place where they are used for the first time. -To avoid piling up too many symbols at places that speak about a~single fixed graph, -this graph is always called~$G$, its set of vertices and edges are denoted by $V$ -and~$E$ respectively, and we~also use~$n$ for the number of its vertices and $m$~for -the number of edges. At places where there could be a~danger of confusion, more explicit notation -is used instead. - -\chapter{Minimum Spanning Trees} - -\section{The Problem} - -The problem of finding a minimum spanning tree of a weighted graph is one of the -best studied problems in the area of combinatorial optimization since its birth. -Its colorful history (see \cite{graham:msthistory} and \cite{nesetril:history} for the full account) -begins in~1926 with the pioneering work of Bor\o{u}vka -\cite{boruvka:ojistem}\foot{See \cite{nesetril:boruvka} for an English translation with commentary.}, -who studied primarily an Euclidean version of the problem related to planning -of electrical transmission lines (see \cite{boruvka:networks}), but gave an efficient -algorithm for the general version of the problem. As it was well before the dawn of graph -theory, the language of his paper was complicated, so we will better state the problem -in contemporary terminology: - -\proclaim{Problem}Given an undirected graph~$G$ with weights $w:E(G)\rightarrow {\bb R}$, -find its minimum spanning tree, defined as follows: - -\defn\id{mstdef}% -For a given graph~$G$ with weights $w:E(G)\rightarrow {\bb R}$: -\itemize\ibull -\:A~subgraph $H\subseteq G$ is called a \df{spanning subgraph} if $V(H)=V(G)$. -\:A~\df{spanning tree} of~$G$ is any spanning subgraph of~$G$ that is a tree. -\:For any subgraph $H\subseteq G$ we define its \df{weight} $w(H):=\sum_{e\in E(H)} w(e)$. -\:A~\df{minimum spanning tree (MST)} of~$G$ is a spanning tree~$T$ such that its weight $w(T)$ - is the smallest possible among all the spanning trees of~$G$. -\:For a disconnected graph, a \df{(minimum) spanning forest (MSF)} is defined as - a union of (minimum) spanning trees of its connected components. -\endlist - -Bor\o{u}vka's work was further extended by Jarn\'\i{}k \cite{jarnik:ojistem}, again in -mostly geometric setting, and he has discovered another efficient algorithm. -In the next 50 years, several significantly faster algorithms were published, ranging -from the $\O(m\timesbeta(m,n))$ time algorithm by Fredman and Tarjan \cite{ft:fibonacci}, -over algorithms with inverse-Ackermann type complexity by Chazelle \cite{chazelle:ackermann} -and Pettie \cite{pettie:ackermann}, to an~algorithm by Pettie \cite{pettie:optimal} -whose time complexity is provably optimal. - -Before we discuss the algorithms, let us review the basic properties of spanning trees. -We will mostly follow the theory developed by Tarjan in~\cite{tarjan:dsna} and show -that the weights on edges are not necessary for the definition of the MST. - -\defnn{Heavy and light edges}\id{heavy}% -Let~$G$ be a~connected graph with edge weights~$w$ and $T$ its spanning tree. Then: -\itemize\ibull -\:For vertices $x$ and $y$, let $T[x,y]$ denote the (unique) path in~$T$ joining $x$ with~$y$. -\:For an edge $e=xy$ we will call $T[e]:=T[x,y]$ the \df{path covered by~$e$} and - the edges of this path \df{edges covered by~$e$}. -\:An edge~$e$ is called \df{light with respect to~$T$} (or just \df{$T$-light}) if it covers a~heavier edge, i.e., if there - is an~edge $f\in T[e]$ such that $w(f) > w(e)$. -\:An edge~$e$ is called \df{$T$-heavy} if it covers a~lighter edge. -\endlist - -\thm -A~spanning tree~$T$ is minimum iff there is no $T$-light edge. - -\thm -If all edge weights are distinct, then the minimum spanning tree is unique. - -\para -When $G$ is a graph with distinct edge weights, we will use $\mst(G)$ to denote -its unique minimum spanning tree. -To simplify the description of MST algorithms, we will assume that the weights -of all edges are distinct and that instead of numeric weights we are given a~\df{comparison oracle.} -The oracle is a~function that answers questions of type ``Is $w(e)1$: -\::For each vertex $v_k$ of~$G$, let $e_k$ be the lightest edge incident to~$v_k$. -\::$T\=T\cup \{ \ell(e_1),\ldots,\ell(e_n) \}$.\cmt{Remember labels of all selected edges.} -\::Contract all edges $e_k$, inheriting labels and weights.\foot{In other words, we will ask the comparison oracle for the edge $\ell(e)$ instead of~$e$.} -\::Flatten $G$ (remove parallel edges and loops). -\algout Minimum spanning tree~$T$. -\endalgo - -\thm -The Contractive Bor\o{u}vka's algorithm finds the MST of the graph given as -its input in time $\O(\min(n^2,m\log n))$. - -We also show that this time bound is tight --- we construct an~explicit -family of graphs on which the algorithm spends $\Theta(m\log n)$ steps. -Given a~planar graph, the algorithm however runs much faster (we get a~linear-time -algorithm much simpler than the one of Matsui \cite{matsui:planar}): - -\thm -When the input graph is planar, the Contractive Bor\o{u}vka's algorithm runs in -time $\O(n)$. - -Graph contractions are indeed a~very powerful tool and they can be used in other MST -algorithms as well. The following lemma shows the gist: - -\lemman{Contraction lemma}\id{contlemma}% -Let $G$ be a weighted graph, $e$~an arbitrary edge of~$\mst(G)$, $G/e$ the multigraph -produced by contracting~$e$ in~$G$, and $\pi$ the bijection between edges of~$G-e$ and -their counterparts in~$G/e$. Then $\mst(G) = \pi^{-1}[\mst(G/e)] + e.$ - -\chapter{Fine Details of Computation} - -\section{Models and machines} - -Traditionally, computer scientists have been using a~variety of computational models -as a~formalism in which their algorithms are stated. If we were studying -NP-complete\-ness, we could safely assume that all these models are equivalent, -possibly up to polynomial slowdown which is negligible. In our case, the -differences between good and not-so-good algorithms are on a~much smaller -scale, so we need to state our computation models carefully and develop -a repertoire of basic data structures tailor-made for the fine details of the -models. In recent decades, most researchers in the area of combinatorial algorithms -have been considering the following two computational models, and we will do likewise. - -The \df{Random Access Machine (RAM)} is not a~single coherent model, but rather a~family -of closely related machines (See Cook and Reckhow \cite{cook:ram} for one of the usual formal definitions -and Hagerup \cite{hagerup:wordram} for a~thorough description of the differences -between the RAM variants.) We will consider the variant usually called the \df{Word-RAM.} -It allows the ``C-language operators'', i.e., arithmetics and bitwise logical operations, -running in constant time on words of a~specified size. - -The \df{Pointer Machine (PM)} also does not seem to have any well established definition. -The various kinds of pointer machines are examined by Ben-Amram in~\cite{benamram:pm}, -but unlike the RAM's they turn out to be equivalent up to constant slowdown. -Our formal definition is closely related to the \em{linking automaton} proposed -by Knuth in~\cite{knuth:fundalg}. - -\section{Bucket sorting and related techniques}\id{bucketsort}% - -In the Contractive Bor\o{u}vka's algorithm, we needed to contract a~given -set of edges in the current graph and then flatten the graph, all this in time $\O(m)$. -This can be easily handled on both the RAM and the PM by bucket sorting. We develop -a~bunch of pointer-based sorting techniques which can be summarized by the following -lemma: - -\lemma -Partitioning of a~collection of sequences $S_1,\ldots,S_n$, whose elements are -arbitrary pointers and symbols from a~finite alphabet, to equality classes can -be performed on the Pointer Machine in time $\O(n + \sum_i \vert S_i \vert)$. - -\para -A~direct consequence of this unification is a~linear-time algorithm for subtree -isomorphism, significantly simpler than the standard one due to Zemlayachenko (see \cite{zemlay:treeiso} -and also Dinitz et al.~\cite{dinitz:treeiso}). When we apply a~similar technique -to general graphs, we get the framework of topological graph computation -of Buchsbaum et al.~\cite{buchsbaum:verify}. - -\defn -A~\df{graph computation} is a~function that takes a~\df{labeled undirected graph} as its input. The labels of -vertices and edges can be arbitrary symbols drawn from a~finite alphabet. The output -of the computation is another labeling of the same graph. This time, the vertices and -edges can be labeled with not only symbols of the alphabet, but also with pointers to the vertices -and edges of the input graph, and possibly also with pointers to outside objects. -A~graph computation is called \df{topological} if it produces isomorphic -outputs for isomorphic inputs. The isomorphism of course has to preserve not only -the structure of the graph, but also the labels in the obvious way. - -\defn -For a~collection~$\C$ of graphs, we define $\vert\C\vert$ as the number of graphs in -the collection and $\Vert\C\Vert$ as their total size, i.e., $\Vert\C\Vert = \sum_{G\in\C} n(G) + m(G)$. - -\thm -Suppose that we have a~topological graph computation~$\cal T$ that can be performed in time -$T(k)$ for graphs on $k$~vertices. Then we can run~$\cal T$ on a~collection~$\C$ -of labeled graphs on~$k$ vertices in time $\O(\Vert\C\Vert + (k+s)^{k(k+2)}\cdot (T(k)+k^2))$, -where~$s$ is a~constant depending only on the number of symbols used as vertex/edge labels. - -\section{Data structures on the RAM}\id{ramds}% - -There is a~lot of data structures designed specifically for the RAM. These structures -take advantage of both indexing and arithmetics and they often surpass the known -lower bounds for the same problem on the~PM. In many cases, they achieve constant time -per operation, at least when either the magnitude of the values or the size of -the data structure is suitably bounded. - -A~classical result of this type is the tree of van Emde Boas~\cite{boas:vebt} -which represents a~subset of the integers $\{0,\ldots,U-1\}$. It allows insertion, -deletion and order operations (minimum, maximum, successor etc.) in time $\O(\log\log U)$, -regardless of the size of the subset. If we replace the heap used in the Jarn\'\i{}k's -algorithm (\ref{jarnik}) by this structure, we immediately get an~algorithm -for finding the MST in integer-weighted graphs in time $\O(m\log\log w_{max})$, -where $w_{max}$ is the maximum weight. - -A~real breakthrough has however been made by Fredman and Willard who introduced -the Fusion trees~\cite{fw:fusion}. They again perform membership and predecessor -operation on a~set of $n$~integers, but with time complexity $\O(\log_W n)$ -per operation on a~Word-RAM with $W$-bit words. This of course assumes that -each element of the set fits in a~single word. As $W$ must at least~$\log n$, -the operations take $\O(\log n/\log\log n)$ time and thus we are able to sort $n$~integers -in time~$o(n\log n)$. This was further improved by Han and Thorup \cite{han:detsort,hanthor:randsort}. - -The Fusion trees themselves have very limited use in graph algorithms, but the -principles behind them are ubiquitous in many other data structures and these -will serve us well and often. We are going to build the theory of Q-heaps, -which will later lead to a~linear-time MST algorithm for arbitrary integer weights. -Other such structures will help us in building linear-time RAM algorithms for computing the ranks -of various combinatorial structures in Chapter~\ref{rankchap}. - -Outside our area, important consequences of RAM data structures include the -Thorup's $\O(m)$ algorithm for single-source shortest paths in undirected -graphs with positive integer weights \cite{thorup:usssp} and his $\O(m\log\log -n)$ algorithm for the same problem in directed graphs \cite{thorup:sssp}. Both -algorithms have been then significantly simplified by Hagerup -\cite{hagerup:sssp}. - -Despite the progress in the recent years, the corner-stone of all RAM structures -is still the representation of combinatorial objects by integers introduced by -Fredman and Willard. -First of all, we observe that we can encode vectors in integers: - -\notan{Bit strings}\id{bitnota}% -We will work with binary representations of natural numbers by strings over the -alphabet $\{\0,\1\}$: we will use $\(x)$ for the number~$x$ written in binary, -$\(x)_b$ for the same padded to exactly $b$ bits by adding leading zeroes, -and $x[k]$ for the value of the $k$-th bit of~$x$ (with a~numbering of bits such that $2^k[k]=1$). -The usual conventions for operations on strings will be utilized: When $s$ -and~$t$ are strings, we write $st$ for their concatenation and -$s^k$ for the string~$s$ repeated $k$~times. -When the meaning is clear from the context, -we will use $x$ and $\(x)$ interchangeably to avoid outbreak of symbols. - -\defn -The \df{bitwise encoding} of a~vector ${\bf x}=(x_0,\ldots,x_{d-1})$ of~$b$-bit numbers -is an~integer~$x$ such that $\(x)=\(x_{d-1})_b\0\(x_{d-2})_b\0\ldots\0\(x_0)_b$. In other -words, $x = \sum_i 2^{(b+1)i}\cdot x_i$. (We have interspersed the elements with \df{separator bits.}) - -\para -If we want to fit the whole vector in a~single machine word, the parameters $b$ and~$d$ must satisfy -the condition $(b+1)d\le W$ (where $W$~is the word size of the machine). -By using multiple-precision arithmetics, we can encode all vectors satisfying $bd=\O(W)$. -We describe how to translate simple vector manipulations to sequences of $\O(1)$ RAM operations -on their codes. For example, we can handle element-wise comparison of vectors, insertion -in a~sorted vector or shuffling elements of a~vector according to a~fixed permutation, -all in $\O(1)$ time. This also implies that several functions on numbers can be performed -in constant time, most notably binary logarithms. -The vector operations then serve as building blocks for construction of the Q-heaps. We get: - -\thm -Let $W$ and~$k$ be positive integers such that $k=\O(W^{1/4})$. Let~$Q$ -be a~Q-heap of at most $k$-elements of $W$~bits each. Then we can perform -Q-heap operations on~$Q$ (insertion, deletion, search for a~given value and search -for the $i$-th smallest element) in constant time on a~Word-RAM with word size~$W$, -after spending time $\O(2^{k^4})$ on the same RAM on precomputing of tables. - -\cor -For every positive integer~$r$ and $\delta>0$ there exists a~data structure -capable of maintaining the minimum of a~set of at most~$r$ word-sized numbers -under insertions and deletions. Each operation takes $\O(1)$ time on a~Word-RAM -with word size $W=\Omega(r^{\delta})$, after spending time -$\O(2^{r^\delta})$ on precomputing of tables. - -\chapter{Advanced MST Algorithms} - -\section{Minor-closed graph classes}\id{minorclosed}% - -The contractive algorithm given in Section~\ref{contalg} has been found to perform -well on planar graphs, but in general its time complexity was not linear. -Can we find any broader class of graphs where the linear bound holds? -The right context turns out to be the minor-closed classes, which are -closed under contractions and have bounded density. - -\defn\id{minordef}% -A~graph~$H$ is a \df{minor} of a~graph~$G$ (written as $H\minorof G$) iff it can be obtained -from a~subgraph of~$G$ by a sequence of simple graph contractions. - -\defn -A~class~$\cal C$ of graphs is \df{minor-closed}, when for every $G\in\cal C$ and -every minor~$H$ of~$G$, the graph~$H$ lies in~$\cal C$ as well. A~class~$\cal C$ is called -\df{non-trivial} if at least one graph lies in~$\cal C$ and at least one lies outside~$\cal C$. - -\example -Non-trivial minor-closed classes include: -planar graphs, -graphs embeddable in any fixed surface (i.e., graphs of bounded genus), -graphs embeddable in~${\bb R}^3$ without knots or without interlocking cycles, -and graphs of bounded tree-width or path-width. - -\para -Many of the nice structural properties of planar graphs extend to -minor-closed classes, too (see Lov\'asz \cite{lovasz:minors} for a~nice survey -of this theory and Diestel \cite{diestel:gt} for some of the deeper results). -For analysis of the contractive algorithm, we will make use of the bounded -density of minor-closed classes: - -\defn\id{density}% -Let $G$ be a~graph and $\cal C$ be a class of graphs. We define the \df{edge density} -$\varrho(G)$ of~$G$ as the average number of edges per vertex, i.e., $m(G)/n(G)$. The -edge density $\varrho(\cal C)$ of the class is then defined as the infimum of $\varrho(G)$ over all $G\in\cal C$. - -\thmn{Density of minor-closed classes, Mader~\cite{mader:dens}} -Every non-trivial minor-closed class of graphs has finite edge density. - -\thmn{MST on minor-closed classes, Mare\v{s} \cite{mm:mst}}\id{mstmcc}% -For any fixed non-trivial minor-closed class~$\cal C$ of graphs, the Contractive Bor\o{u}vka's -algorithm (\ref{contbor}) finds the MST of any graph of this class in time -$\O(n)$. (The constant hidden in the~$\O$ depends on the class.) - -\paran{Local contractions}\id{nobatch}% -The contractive algorithm uses ``batch processing'' to perform many contractions -in a single step. It is also possible to perform them one edge at a~time, -batching only the flattenings. A~contraction of an edge~$uv$ can be done in time~$\O(\deg(u))$, -so we have to make sure that there is a~steady supply of low-degree vertices. -It indeed is in minor-closed classes: - -\lemman{Low-degree vertices}\id{lowdeg}% -Let $\cal C$ be a graph class with density~$\varrho$ and $G\in\cal C$ a~graph -with $n$~vertices. Then at least $n/2$ vertices of~$G$ have degree at most~$4\varrho$. - -This leads to the following algorithm: - -\algn{Local Bor\o{u}vka's Algorithm, Mare\v{s} \cite{mm:mst}}% -\algo -\algin A~graph~$G$ with an edge comparison oracle and a~parameter~$t\in{\bb N}$. -\:$T\=\emptyset$. -\:$\ell(e)\=e$ for all edges~$e$. -\:While $n(G)>1$: -\::While there exists a~vertex~$v$ such that $\deg(v)\le t$: -\:::Select the lightest edge~$e$ incident with~$v$. -\:::Contract~$e$. -\:::$T\=T + \ell(e)$. -\::Flatten $G$, removing parallel edges and loops. -\algout Minimum spanning tree~$T$. -\endalgo - -\thm -When $\cal C$ is a minor-closed class of graphs with density~$\varrho$, the -Local Bor\o{u}vka's Algorithm with the parameter~$t$ set to~$4\varrho$ -finds the MST of any graph from this class in time $\O(n)$. (The constant -in the~$\O$ depends on~the class.) - -\section{Iterated algorithms}\id{iteralg}% - -We have seen that the Jarn\'\i{}k's Algorithm \ref{jarnik} runs in $\Theta(m\log n)$ time. -Fredman and Tarjan \cite{ft:fibonacci} have shown a~faster implementation using their Fibonacci -heaps, which runs in time $\O(m+n\log n)$. This is $\O(m)$ whenever the density of the -input graph reaches $\Omega(\log n)$. This suggests that we could combine the algorithm with -another MST algorithm, which identifies a~subset of the MST edges and contracts -them to increase the density of the graph. For example, if we perform several Bor\o{u}vka -steps and then we run the Jarn\'\i{}k's algorithm, we find the MST in time $\O(m\log\log n)$. - -Actually, there is a~much better choice of the algorithms to combine: use the -Jarn\'\i{}k's algorithm with a~Fibonacci heap multiple times, each time stopping it after a~while. -A~good choice of the stopping condition is to place a~limit on the size of the heap. -We start with an~arbitrary vertex, grow the tree as usually and once the heap gets too large, -we conserve the current tree and start with a~different vertex and an~empty heap. When this -process runs out of vertices, it has identified a~sub-forest of the MST, so we can -contract the edges of~this forest and iterate. This improves the time complexity -significantly: - -\thm\id{itjarthm}% -The Iterated Jarn\'\i{}k's algorithm finds the MST of the input graph in time -$\O(m\timesbeta(m,n))$, where $\beta(m,n):=\min\{ i \mid \log^{(i)}n \le m/n \}$. - -\cor -The Iterated Jarn\'\i{}k's algorithm runs in time $\O(m\log^* n)$. - -\paran{Integer weights}% -The algorithm spends most of the time in phases which have small heaps. Once the -heap grows to $\Omega(\log^{(k)} n)$ for any fixed~$k$, the graph gets dense enough -to guarantee that at most~$k$ phases remain. This means that if we are able to -construct a~heap of size $\Omega(\log^{(k)} n)$ with constant time per operation, -we can get a~linear-time algorithm for MST. This is the case when the weights are -integers (we can use the Q-heap trees from Section~\ref{ramds}). - -\thmn{MST for integer weights, Fredman and Willard \cite{fw:transdich}}\id{intmst}% -MST of a~graph with integer edge weights can be found in time $\O(m)$ on the Word-RAM. - -\section{Verification of minimality}\id{verifysect}% - -Now we will turn our attention to a~slightly different problem: given a~spanning -tree, how to verify that it is minimum? We will show that this can be achieved -in linear time and it will serve as a~basis for a~randomized linear-time -MST algorithm in the next section. - -MST verification has been studied by Koml\'os \cite{komlos:verify}, who has -proven that $\O(m)$ edge comparisons are sufficient, but his algorithm needed -super-linear time to find the edges to compare. Dixon, Rauch and Tarjan \cite{dixon:verify} -have later shown that the overhead can be reduced -to linear time on the RAM using preprocessing and table lookup on small -subtrees. Later, King has given a~simpler algorithm in \cite{king:verifytwo}. - -To verify that a~spanning tree~$T$ is minimum, it is sufficient to check that all -edges outside~$T$ are $T$-heavy. For each edge $uv\in E\setminus T$, we will -find the heaviest edge of the tree path $T[u,v]$ (we will call it the \df{peak} -of the path) and compare its weight to $w(uv)$. We have therefore transformed -the MST verification to the problem of finding peaks for a~set of \df{query -paths} on a~given tree. By a~sequence of further transformations, we can even -assume that the given tree is \df{complete branching} (all vertices are on -the same level and internal vertices always have outdegree~2) and that the -query paths join a~vertex with one of its ancestors. - -Koml\'os has given a~simple algorithm that traverses the complete branching -tree recursively. At each moment, it maintains an~array of peaks of the restrictions -of the query paths to the subtree below the current vertex. If we account for the -comparisons performed by this algorithm carefully and express the bound in terms -of the size of the original problem (before all the transformations), we get: - -\thmn{Verification of the MST, Koml\'os \cite{komlos:verify}}\id{verify}% -For every weighted graph~$G$ and its spanning tree~$T$, it is sufficient to -perform $\O(m)$ comparisons of edge weights to determine whether~$T$ is minimum -and to find all $T$-light edges in~$G$. - -It remains to demonstrate that the overhead of the algorithm needed to find -the required comparisons and to infer the peaks from their results can be decreased, -so that it gets bounded by the number of comparisons and therefore also by $\O(m)$. -We will follow the idea of King from \cite{king:verifytwo}, but as we have the power -of the RAM data structures from Section~\ref{ramds} at our command, the low-level -details will be easier. Still, the construction is rather technical, so we omit -it from this abstract and state only the final theorem: - -\thmn{Verification of MST on the RAM}\id{ramverify}% -There is a~RAM algorithm which for every weighted graph~$G$ and its spanning tree~$T$ -determines whether~$T$ is minimum and finds all $T$-light edges in~$G$ in time $\O(m)$. - -\section{A randomized algorithm}\id{randmst}% - -When we analysed the Contractive Bor\o{u}vka's algorithm in Section~\ref{contalg}, -we observed that while the number of vertices per iteration decreases exponentially, -the number of edges generally does not, so we spend $\Theta(m)$ time on every phase. -Karger, Klein and Tarjan \cite{karger:randomized} have overcome this problem by -combining the Bor\o{u}vka's algorithm with filtering based on random sampling. -This leads to a~randomized algorithm which runs in linear expected time. - -The principle of the filtering is simple: Let us consider any spanning tree~$T$ -of the input graph~$G$. Each edge of~$G$ that is $T$-heavy is the heaviest edge -of some cycle, so by the Red lemma it cannot participate in -the MST of~$G$. We can therefore discard all $T$-heavy edges and continue with -finding the MST on the reduced graph. Of course, not all choices of~$T$ are equally -good, but it will soon turn out that when we take~$T$ as the MST of a~randomly selected -subgraph, only a~small expected number of edges remains: - -\lemman{Random sampling, Karger \cite{karger:sampling}}\id{samplemma}% -Let $H$~be a~subgraph of~$G$ obtained by including each edge independently -with probability~$p$. Let further $F$~be the minimum spanning forest of~$H$. Then the -expected number of $F$-nonheavy\foot{That is, $F$-light edges and also edges of~$F$ itself.} -edges in~$G$ is at most $n/p$. - -\para -We will formulate the algorithm as a~doubly-recursive procedure. It alternatively -performs steps of the Bor\o{u}vka's algorithm and filtering based on the above lemma. -The first recursive call computes the MSF of the sampled subgraph, the second one -finds the MSF of the original graph, but without the heavy edges. - -\algn{MSF by random sampling --- the KKT algorithm}\id{kkt}% -\algo -\algin A~graph $G$ with an~edge comparison oracle. -\:Remove isolated vertices from~$G$. If no vertices remain, stop and return an~empty forest. -\:Perform two Bor\o{u}vka steps (iterations of Algorithm \ref{contbor}) on~$G$ and - remember the set~$B$ of the edges having been contracted. -\:Select a~subgraph~$H\subseteq G$ by including each edge independently with - probability $1/2$. -\:$F\=\msf(H)$ calculated recursively. -\:Construct $G'\subseteq G$ by removing all $F$-heavy edges of~$G$. -\:$R\=\msf(G')$ calculated recursively. -\:Return $R\cup B$. -\algout The minimum spanning forest of~$G$. -\endalgo - -\>A~careful analysis of this algorithm, based on properties of its recursion tree -and on the peak-finding algorithm of the previous section, yields the following time bounds: - -\thm -The KKT algorithm runs in time $\O(\min(n^2,m\log n))$ in the worst case on the RAM. -The expected time complexity is $\O(m)$. - -\chapter{Approaching Optimality}\id{optchap}% - -\section{Soft heaps}\id{shsect}% - -A~vast majority of MST algorithms that we have encountered so far is based on -the Tarjan's Blue rule (Lemma \ref{bluelemma}), the only exception being the -randomized KKT algorithm, which also used the Red rule (Lemma \ref{redlemma}). Recently, Chazelle -\cite{chazelle:ackermann} and Pettie \cite{pettie:ackermann} have presented new -deterministic algorithms for the MST which are also based on the combination of -both rules. They have reached worst-case time complexity -$\O(m\timesalpha(m,n))$ on the Pointer Machine. We will devote this chapter to -their results and especially to another algorithm by Pettie and Ramachandran -\cite{pettie:optimal} which is provably optimal. - -At the very heart of all these algorithms lies the \df{soft heap} discovered by -Chazelle \cite{chazelle:softheap}. It is a~meldable priority queue, roughly -similar to the Vuillemin's binomial heaps \cite{vuillemin:binheap} or Fredman's -and Tarjan's Fibonacci heaps \cite{ft:fibonacci}. The soft heaps run faster at -the expense of \df{corrupting} a~fraction of the inserted elements by raising -their values (the values are however never lowered). This allows for -a~trade-off between accuracy and speed, controlled by a~parameter~$\varepsilon$. - -In the thesis, we describe the exact mechanics of the soft heaps and analyse its complexity. -The important properties are characterized by the following theorem: - -\thmn{Performance of soft heaps, Chazelle \cite{chazelle:softheap}}\id{softheap}% -A~soft heap with error rate~$\varepsilon$ ($0<\varepsilon\le 1/2$) processes -a~sequence of operations starting with an~empty heap and containing $n$~\s -in time $\O(n\log(1/\varepsilon))$ on the Pointer Machine. At every moment, the -heap contains at most $\varepsilon n$ corrupted items. - -\section{Robust contractions} - -Having the soft heaps at hand, we would like to use them in a~conventional MST -algorithm in place of a~normal heap. We can for example try implanting the soft heap -in the Jarn\'i{}k's algorithm, preferably in the earlier -version without Fibonacci heaps as the soft heaps lack the \ operation. -This brave, but somewhat simple-minded attempt is however doomed to -fail because of corruption of items inside the soft heap. -While the basic structural properties of MST's no longer hold in corrupted graphs, -there is a~weaker form of the Contraction lemma that takes the corrupted edges into account. -Before we prove this lemma, we expand our awareness of subgraphs which can be contracted. - -\defn -A~subgraph $C\subseteq G$ is \df{contractible} iff for every pair of edges $e,f\in\delta(C)$\foot{That is, -of~$G$'s edges with exactly one endpoint in~$C$.} there exists a~path in~$C$ connecting the endpoints -of the edges $e,f$ such that all edges on this path are lighter than either $e$ or~$f$. - -For example, when we stop the Jarn\'\i{}k's algorithm at some moment and -we take a~subgraph~$C$ induced by the constructed tree, this subgraph is contractible. -We can now easily reformulate the Contraction lemma (\ref{contlemma}) in the language -of contractible subgraphs: - -\lemman{Generalized contraction} -When~$C\subseteq G$ is a~contractible subgraph, then $\msf(G)=\msf(C) \cup \msf(G/C)$. - -Let us bring corruption back to the game and state a~``robust'' version -of this lemma. - -\nota\id{corrnota}% -When~$G$ is a~weighted graph and~$R$ a~subset of its edges, we will use $G\crpt -R$ to denote an arbitrary graph obtained from~$G$ by increasing the weights of -some of the edges in~$R$. -Whenever~$C$ is a~subgraph of~$G$, we will use $R^C$ to refer to the edges of~$R$ with -exactly one endpoint in~$C$ (i.e., $R^C = R\cap \delta(C)$). - -\lemman{Robust contraction, Chazelle \cite{chazelle:almostacker}}\id{robcont}% -Let $G$ be a~weighted graph and $C$~its subgraph contractible in~$G\crpt R$ -for some set~$R$ of edges. Then $\msf(G) \subseteq \msf(C) \cup \msf((G/C) \setminus R^C) \cup R^C$. - -\para -We will now mimic the Iterated Jarn\'\i{}k's algorithm. We will partition the given graph to a~collection~$\C$ -of non-overlapping contractible subgraphs called \df{clusters} and we put aside all edges that got corrupted in the process. -We recursively compute the MSF of those subgraphs and of the contracted graph. Then we take the -union of these MSF's and add the corrupted edges. According to the previous lemma, this does not produce -the MSF of~$G$, but a~sparser graph containing it, on which we can continue. -%%The following theorem describes the properties of this partition: - -\thmn{Partitioning to contractible clusters, Chazelle \cite{chazelle:almostacker}}\id{partthm}% -Given a~weighted graph~$G$ and parameters $\varepsilon$ ($0<\varepsilon\le 1/2$) -and~$t$, we can construct a~collection $\C=\{C_1,\ldots,C_k\}$ of clusters and a~set~$R^\C$ of edges such that: - -\numlist\ndotted -\:All the clusters and the set~$R^\C$ are mutually edge-disjoint. -\:Each cluster contains at most~$t$ vertices. -\:Each vertex of~$G$ is contained in at least one cluster. -\:The connected components of the union of all clusters have at least~$t$ vertices each, - except perhaps for those which are equal to a~connected component of $G\setminus R^\C$. -\:$\vert R^\C\vert \le 2\varepsilon m$. -\:$\msf(G) \subseteq \bigcup_i \msf(C_i) \cup \msf\bigl((G / \bigcup_i C_i) \setminus R^\C\bigr) \cup R^\C$. -\:The construction takes $\O(n+m\log (1/\varepsilon))$ time. -\endlist - -\section{Decision trees}\id{dtsect}% - -The Pettie's and Ramachandran's algorithm combines the idea of robust partitioning with optimal decision -trees constructed by brute force for very small subgraphs. -%%Formally, the decision trees are defined as follows: -Let us define them first: - -\defnn{Decision trees and their complexity}\id{decdef}% -A~\df{MSF decision tree} for a~graph~$G$ is a~binary tree. Its internal vertices -are labeled with pairs of $G$'s edges to be compared, each of the two outgoing tree edges -corresponds to one possible result of the comparison. -Leaves of the tree are labeled with spanning trees of the graph~$G$. - -A~\df{computation} of the decision tree on a~specific permutation of edge weights -in~$G$ is the path from the root to a~leaf such that the outcome of every comparison -agrees with the edge weights. The result of the computation is the spanning tree -assigned to its final leaf. -A~decision tree is \df{correct} iff for every permutation the corresponding -computation results in the real MSF of~$G$ with the particular weights. - -The \df{time complexity} of a~decision tree is defined as its depth. It therefore -bounds the number of comparisons spent on every path. (It need not be equal since -some paths need not correspond to an~actual computation --- the sequence of outcomes -on the path could be unsatisfiable.) - -A~decision tree is called \df{optimal} if it is correct and its depth is minimum possible -among the correct decision trees for the given graph. -We will denote an~arbitrary optimal decision tree for~$G$ by~${\cal D}(G)$ and its -complexity by~$D(G)$. - -The \df{decision tree complexity} $D(m,n)$ of the MSF problem is the maximum of~$D(G)$ -over all graphs~$G$ with $n$~vertices and~$m$ edges. - -\obs -Decision trees are the most general deterministic comparison-based computation model possible. -The only operations that count in its time complexity are comparisons. All -other computation is free, including solving NP-complete problems or having -access to an~unlimited source of non-uniform constants. The decision tree -complexity is therefore an~obvious lower bound on the time complexity of the -problem in all other comparison-based models. - -The downside is that we do not know any explicit construction of the optimal -decision trees, nor even a~non-constructive proof of their complexity. -On the other hand, the complexity of any existing comparison-based algorithm -can be used as an~upper bound on the decision tree complexity. Also, we can -construct an~optimal decision tree using brute force: - -\lemma -An~optimal MST decision tree for a~graph~$G$ on~$n$ vertices can be constructed on -the Pointer Machine in time $\O(2^{2^{4n^2}})$. - -\section{An optimal algorithm}\id{optalgsect}% - -Once we have developed the soft heaps, partitioning and MST decision trees, -it is now simple to state the Pettie's and Ramachandran's MST algorithm -and prove that it is asymptotically optimal among all MST algorithms in -comparison-based models. Several standard MST algorithms from the previous -chapters will also play their roles. -We will describe the algorithm as a~recursive procedure: - -\algn{Optimal MST algorithm, Pettie and Ramachandran \cite{pettie:optimal}}\id{optimal}% -\algo -\algin A~connected graph~$G$ with an~edge comparison oracle. -\:If $G$ has no edges, return an~empty tree. -\:$t\=\lfloor\log^{(3)} n\rfloor$. \cmt{the size of clusters} -\:Call the partitioning procedure (\ref{partthm}) on $G$ and $t$ with $\varepsilon=1/8$. It returns - a~collection~$\C=\{C_1,\ldots,C_k\}$ of clusters and a~set~$R^\C$ of corrupted edges. -\:$F_i \= \mst(C_i)$ for all~$i$, obtained using optimal decision trees. -\:$G_A \= (G / \bigcup_i C_i) \setminus R^\C$. \cmt{the contracted graph} -\:$F_A \= \msf(G_A)$ calculated by the Iterated Jarn\'\i{}k's algorithm (see Section \ref{iteralg}). -\:$G_B \= \bigcup_i F_i \cup F_A \cup R^\C$. \cmt{combine subtrees with corrupted edges} -\:Run two Bor\o{u}vka steps (iterations of the Contractive Bor\o{u}vka's algorithm, \ref{contbor}) on~$G_B$, - getting a~contracted graph~$G_C$ and a~set~$F_B$ of MST edges. -\:$F_C \= \mst(G_C)$ obtained by a~recursive call to this algorithm. -\:Return $F_B \cup F_C$. -\algout The minimum spanning tree of~$G$. -\endalgo - -\>Correctness of this algorithm immediately follows from the Partitioning theorem (\ref{partthm}) -and from the proofs of the respective algorithms used as subroutines. As for time complexity, we prove: - -\thm -The time complexity of the Optimal algorithm is $\Theta(D(m,n))$. - -\paran{Complexity of MST}% -As we have already noted, the exact decision tree complexity $D(m,n)$ of the MST problem -is still open and so therefore is the time complexity of the optimal algorithm. However, -every time we come up with another comparison-based algorithm, we can use its complexity -(or more specifically the number of comparisons it performs, which can be even lower) -as an~upper bound on the optimal algorithm. -The best explicit comparison-based algorithm known to date has been discovered by Chazelle -\cite{chazelle:ackermann} and independently by Pettie \cite{pettie:ackermann}. It achieves complexity $\O(m\timesalpha(m,n))$. -Using any of these results, we can prove an~Ackermannian upper bound on the -optimal algorithm: - -\thm -The time complexity of the Optimal algorithm is $\O(m\timesalpha(m,n))$. - -\chapter{Dynamic Spanning Trees}\id{dynchap}% - -\section{Dynamic graph algorithms} - -In many applications, we often need to solve a~certain graph problem for a~sequence of graphs that -differ only a~little, so recomputing the solution for every graph from scratch would be a~waste of -time. In such cases, we usually turn our attention to \df{dynamic graph algorithms.} A~dynamic -algorithm is in fact a~data structure that remembers a~graph. It offers operations that modify the -structure of the graph and also operations that query the result of the problem for the current -state of the graph. A~typical example of a~problem of this kind is dynamic maintenance of connected -components: - -\problemn{Dynamic connectivity} -Maintain an~undirected graph under a~sequence of the following operations: -\itemize\ibull -\:$\(n)$ --- Create a~graph with $n$~isolated vertices $\{1,\ldots,n\}$. -(It is possible to modify the structure to support dynamic addition and removal of vertices, too.) -\:$\(G,u,v)$ --- Insert an~edge $uv$ to~$G$ and return its unique -identifier. This assumes that the edge did not exist yet. -\:$\(G,e)$ --- Delete an~edge specified by its identifier from~$G$. -\:$\(G,u,v)$ --- Test if vertices $u$ and~$v$ are in the same connected component of~$G$. -\endlist - -\>In this chapter, we will focus on the dynamic version of the minimum spanning forest. -This problem seems to be intimately related to the dynamic connectivity. Indeed, all known -algorithms for dynamic connectivity maintain some sort of a~spanning forest. -This suggests that a~dynamic MSF algorithm could be obtained by modifying the -mechanics of the data structure to keep the forest minimum. -We however have to answer one important question first: What should be the output of -our MSF data structure? Adding an~operation that returns the MSF of the current -graph would be of course possible, but somewhat impractical as this operation would have to -spend $\Omega(n)$ time on the mere writing of its output. A~better way seems to -be making the \ and \ operations report the list of modifications -of the MSF implied by the change in the graph. It is easy to prove that $\O(1)$ -modifications always suffice, so we can formulate our problem as follows: - -\problemn{Dynamic minimum spanning forest} -Maintain an~undirected graph with distinct weights on edges (drawn from a~totally ordered set) -and its minimum spanning forest under a~sequence of the following operations: -\itemize\ibull -\:$\(n)$ --- Create a~graph with $n$~isolated vertices $\{1,\ldots,n\}$. -\:$\(G,u,v,w)$ --- Insert an~edge $uv$ of weight~$w$ to~$G$. Return its unique - identifier and the list of additions and deletions of edges in $\msf(G)$. -\:$\(G,e)$ --- Delete an~edge specified by its identifier from~$G$. - Return the list of additions and deletions of edges in $\msf(G)$. -\endlist - -\paran{Incremental MSF}% -In case only edge insertions are allowed, the problem reduces to finding the heaviest -edge (peak) on the tree path covered by the newly inserted edge and replacing the peak -if needed. This can be handled quite efficiently by using the Link-Cut trees of Sleator -and Tarjan \cite{sleator:trees}. We obtain logarithmic time bound: - -\thmn{Incremental MSF} -When only edge insertions are allowed, the dynamic MSF can be maintained in time $\O(\log n)$ -amortized per operation. - -\section{Dynamic connectivity} - -The fully dynamic connectivity problem has a~long and rich history. In the 1980's, Frederickson \cite{frederickson:dynamic} -has used his topological trees to construct a~dynamic connectivity algorithm of complexity $\O(\sqrt m)$ per update and -$\O(1)$ per query. Eppstein et al.~\cite{eppstein:sparsify} have introduced a~sparsification technique which can bring the -updates down to $\O(\sqrt n)$. Later, several different algorithms with complexity on the order of $n^\varepsilon$ -were presented by Henzinger and King \cite{henzinger:mst} and also by Mare\v{s} \cite{mares:dga}. -A~polylogarithmic time bound was first reached by the randomized algorithm of Henzinger and King \cite{henzinger:randdyn}. -The best result known as of now is the $\O(\log^2 n)$ time deterministic algorithm by Holm, -de~Lichtenberg and Thorup \cite{holm:polylog}, which will we describe in this section. - -The algorithm will maintain a~spanning forest~$F$ of the current graph~$G$, represented by an~ET-tree -which will be used to answer connectivity queries. The edges of~$G\setminus F$ will be stored as~non-tree -edges in the ET-tree. Hence, an~insertion of an~edge to~$G$ either adds it to~$F$ or inserts it as non-tree. -Deletions of non-tree edges are also easy, but when a~tree edge is deleted, we have to search for its -replacement among the non-tree edges. - -To govern the search in an~efficient way, we will associate each edge~$e$ with a~level $\ell(e) \le -L = \lfloor\log_2 n\rfloor$. For each level~$i$, we will use~$F_i$ to denote the subforest -of~$F$ containing edges of level at least~$i$. Therefore $F=F_0 \supseteq F_1 \supseteq \ldots \supseteq F_L$. -We will maintain the following \em{invariants:} - -{\narrower -\def\iinv{{\bo I\the\itemcount~}} -\numlist\iinv -\:$F$~is the maximum spanning forest of~$G$ with respect to the levels. (In other words, -if $uv$ is a~non-tree edge, then $u$ and~$v$ are connected in~$F_{\ell(uv)}$.) -\:For each~$i$, the components of~$F_i$ have at most $\lfloor n/2^i \rfloor$ vertices each. -(This implies that it does not make sense to define~$F_i$ for $i>L$, because it would be empty -anyway.) -\endlist -} - -At the beginning, the graph contains no edges, so both invariants are trivially -satisfied. Newly inserted edges enter level~0, which cannot break I1 nor~I2. - -When we delete a~tree edge at level~$\ell$, we split a~tree~$T$ of~$F_\ell$ to two -trees $T_1$ and~$T_2$. Without loss of generality, let us assume that $T_1$ is the -smaller one. We will try to find the replacement edge of the highest possible -level that connects the spanning tree back. From I1, we know that such an~edge cannot belong to -a~level greater than~$\ell$, so we start looking for it at level~$\ell$. According -to~I2, the tree~$T$ had at most $\lfloor n/2^\ell\rfloor$ vertices, so $T_1$ has -at most $\lfloor n/2^{\ell+1} \rfloor$ of them. Thus we can move all level~$\ell$ -edges of~$T_1$ to level~$\ell+1$ without violating either invariant. - -We now start enumerating the non-tree edges incident with~$T_1$. Each such edge -is either local to~$T_1$ or it joins $T_1$ with~$T_2$. We will therefore check each edge -whether its other endpoint lies in~$T_2$ and if it does, we have found the replacement -edge, so we insert it to~$F_\ell$ and stop. Otherwise we move the edge one level up. (This -will be the grist for the mill of our amortization argument: We can charge most of the work on level -increases and we know that the level of each edge can reach at most~$L$.) - -If the non-tree edges at level~$\ell$ are exhausted, we try the same in the next -lower level and so on. If there is no replacement edge at level~0, the tree~$T$ -remains disconnected. - -The implementation uses the Eulerian Tour trees of Henzinger and King \cite{henzinger:randdyn} -to represent the forests~$F_\ell$ together with the non-tree edges at each particular level. -A~simple amortized analysis using the levels yields the following result: - -\thmn{Fully dynamic connectivity, Holm et al.~\cite{holm:polylog}}\id{dyncon}% -Dynamic connectivity can be maintained in time $\O(\log^2 n)$ amortized per -\ and \ and in time $\O(\log n/\log\log n)$ per \ -in the worst case. - -\rem\id{dclower}% -An~$\Omega(\log n/\log\log n)$ lower bound for the amortized complexity of the dynamic connectivity -problem has been proven by Henzinger and Fredman \cite{henzinger:lowerbounds} in the cell -probe model with $\O(\log n)$-bit words. Thorup has answered by a~faster algorithm -\cite{thorup:nearopt} that achieves $\O(\log n\log^3\log n)$ time per update and -$\O(\log n/\log^{(3)} n)$ per query on a~RAM with $\O(\log n)$-bit words. (He claims -that the algorithm runs on a~Pointer Machine, but it uses arithmetic operations, -so it does not fit the definition of the PM we use. The algorithm only does not -need direct indexing of arrays.) So far, it is not known how to extend this algorithm -to fit our needs, so we omit the details. - -\section{Dynamic spanning forests}\id{dynmstsect}% - -Let us turn our attention back to the dynamic MSF. -Most of the early algorithms for dynamic connectivity also imply $\O(n^\varepsilon)$ -algorithms for dynamic maintenance of the MSF. Henzinger and King \cite{henzinger:twoec,henzinger:randdyn} -have generalized their randomized connectivity algorithm to maintain the MSF in $\O(\log^5 n)$ time per -operation, or $\O(k\log^3 n)$ if only $k$ different values of edge weights are allowed. They have solved -the decremental version of the problem first (which starts with a~given graph and only edge deletions -are allowed) and then presented a~general reduction from the fully dynamic MSF to its decremental version. -We will describe the algorithm of Holm, de Lichtenberg and Thorup \cite{holm:polylog}, who have followed -the same path. They have modified their dynamic connectivity algorithm to solve the decremental MSF -in $\O(\log^2 n)$ and obtained the fully dynamic MSF working in $\O(\log^4 n)$ per operation. - -\paran{Decremental MSF}% -Turning the algorithm from the previous section to the decremental MSF requires only two -changes: First, we have to start with the forest~$F$ equal to the MSF of the initial -graph. As we require to pay $\O(\log^2 n)$ for every insertion, we can use almost arbitrary -MSF algorithm to find~$F$. Second, when we search for an~replacement edge, we need to pick -the lightest possible choice. We will therefore use a~weighted version of the ET-trees. -We must ensure that the lower levels cannot contain a~lighter replacement edge, -but fortunately the light edges tend to ``bubble up'' in the hierarchy of -levels. This can be formalized in form of the following invariant: - -{\narrower -\def\iinv{{\bo I\the\itemcount~}} -\numlist\iinv -\itemcount=2 -\:On every cycle, the heaviest edge has the smallest level. -\endlist -} - -\>This immediately implies that we always select the right replacement edge: - -\lemma\id{msfrepl}% -Let $F$~be the minimum spanning forest and $e$ any its edge. Then among all replacement -edges for~$e$, the lightest one is at the maximum level. - -A~brief analysis also shows that the invariant I3 is observed by all operations -on the structure. We can conclude: - -\thmn{Decremental MSF, Holm et al.~\cite{holm:polylog}} -When we start with a~graph on $n$~vertices with~$m$ edges and we perform a~sequence of -edge deletions, the MSF can be initialized in time $\O((m+n)\cdot\log^2 n)$ and then -updated in time $\O(\log^2 n)$ amortized per operation. - -\paran{Fully dynamic MSF}% -The decremental MSF algorithm can be turned to a~fully dynamic one by a~blackbox -reduction of Holm et al.: - -\thmn{MSF dynamization, Holm et al.~\cite{holm:polylog}} -Suppose that we have a~decremental MSF algorithm with the following properties: -\numlist\ndotted -\:For any $a$,~$b$, it can be initialized on a~graph with~$a$ vertices and~$b$ edges. -\:Then it executes an~arbitrary sequence of deletions in time $\O(b\cdot t(a,b))$, where~$t$ is a~non-decreasing function. -\endlist -\>Then there exists a~fully dynamic MSF algorithm for a~graph on $n$~vertices, starting -with no edges, that performs $m$~insertions and deletions in amortized time: -$$ -\O\left( \log^3 n + \sum_{i=1}^{\log m} \sum_{j=1}^i \; t(\min(n,2^j), 2^j) \right) \hbox{\quad per operation.} -$$ - -\corn{Fully dynamic MSF}\id{dynmsfcorr}% -There is a~fully dynamic MSF algorithm that works in time $\O(\log^4 n)$ amortized -per operation for graphs on $n$~vertices. - -\paran{Dynamic MSF with limited edge weights}% -If the set from which the edge weights are drawn is small, we can take a~different -approach. If only two values are allowed, we split the graph to subgraphs $G_1$ and~$G_2$ -induced by the edges of the respective weights and we maintain separate connectivity -structures (together with a~spanning tree) for $G_1$ and $G_2 \cup T_1$ (where $T_1$ -is a~spanning tree of~$G_1$). We can easily modify the structure for $G_2\cup -T_1$ to prefer the edges of~$T_1$. This ensures that the spanning tree of $G_2\cup T_1$ -will be the MST of the whole~$G$. - -If there are more possible values, we simply iterate this construction: the $i$-th -structure contains edges of weight~$i$ and the edges of the spanning tree from the -$(i-1)$-th structure. We get: - -\thmn{MSF with limited edge weights} -There is a~fully dynamic MSF algorithm that works in time $\O(k\cdot\log^2 n)$ amortized -per operation for graphs on $n$~vertices with only $k$~distinct edge weights allowed. - -\section{Almost minimum trees}\id{kbestsect}% - -In some situations, finding the single minimum spanning tree is not enough and we are interested -in the $K$~lightest spanning trees, usually for some small value of~$K$. Katoh, Ibaraki -and Mine \cite{katoh:kmin} have given an~algorithm of time complexity $\O(m\log\beta(m,n) + Km)$, -building on the MST algorithm of Gabow et al.~\cite{gabow:mst}. -Subsequently, Eppstein \cite{eppstein:ksmallest} has discovered an~elegant preprocessing step which allows to reduce -the running time to $\O(m\log\beta(m,n) + \min(K^2,Km))$ by eliminating edges -which are either present in all $K$ trees or in none of them. -We will show a~variant of their algorithm based on the MST verification -procedure of Section~\ref{verifysect}. - -In this section, we will require the edge weights to be numeric, because -comparisons are certainly not sufficient to determine the second best spanning tree. We will -assume that our computation model is able to add, subtract and compare the edge weights -in constant time. -Let us focus on finding the second lightest spanning tree first. - -\paran{Second lightest spanning tree}% -Suppose that we have a~weighted graph~$G$ and a~sequence $T_1,\ldots,T_z$ of all its spanning -trees. Also suppose that the weights of these spanning trees are distinct and that the sequence -is ordered by weight, i.e., $w(T_1) < \ldots < w(T_z)$ and $T_1 = \mst(G)$. Let us observe -that each tree is similar to at least one of its predecessors: - -\lemman{Difference lemma}\id{kbl}% -For each $i>1$ there exists $jThus we can run the previous algorithm for finding the best edge exchange -on both~$G_1$ and~$G_2$ and find~$T_3$ again in time $\O(m)$. - -\paran{Further spanning trees}% -The construction of auxiliary graphs can be iterated to obtain $T_1,\ldots,T_K$ -for an~arbitrary~$K$. We will build a~\df{meta-tree} of auxiliary graphs. Each node of this meta-tree -carries a~graph and its minimum spanning tree. The root node contains~$(G,T_1)$, -its sons have $(G_1,T_1/e)$ and $(G_2,T_2)$. When $T_3$ is obtained by an~exchange -in one of these sons, we attach two new leaves to that son and we let them carry the two auxiliary -graphs derived by contracting or deleting the exchanged edge. Then we find the best -edge exchanges among all leaves of the new meta-tree and repeat the process. By Observation \ref{tbobs}, -each spanning tree of~$G$ is generated exactly once. The Difference lemma guarantees that -the trees are enumerated in the increasing order. So we get: - -\lemma\id{kbestl}% -Given~$G$ and~$T_1$, we can find $T_2,\ldots,T_K$ in time $\O(Km + K\log K)$. - -\paran{Invariant edges}% -Our algorithm can be further improved for small values of~$K$ (which seems to be the common -case in most applications) by the reduction of Eppstein \cite{eppstein:ksmallest}. -He has proven that there are many edges of~$T_1$ -which are guaranteed to be contained in $T_2,\ldots,T_K$ as well, and likewise there are -many edges of $G\setminus T_1$ which are excluded from all those spanning trees. -When we combine this with the previous construction, we get the following theorem: - -\thmn{Finding $K$ lightest spanning trees}\id{kbestthm}% -For a~given graph~$G$ with real edge weights and a~positive integer~$K$, the $K$~best spanning trees can be found -in time $\O(m\timesalpha(m,n) + \min(K^2,Km + K\log K))$. - -\chapter{Ranking Combinatorial Structures}\id{rankchap}% - -\section{Ranking and unranking}\id{ranksect}% - -The techniques for building efficient data structures on the RAM, which we have described -in Section~\ref{ramds}, can be also used for a~variety of problems related -to ranking of combinatorial structures. Generally, the problems are stated -in the following way: - -\defn\id{rankdef}% -Let~$C$ be a~set of objects and~$\prec$ a~linear order on~$C$. The \df{rank} -$R_{C,\prec}(x)$ of an~element $x\in C$ is the number of elements $y\in C$ such that $y\prec x$. -We will call the function $R_{C,\prec}$ the \df{ranking function} for $C$ ordered by~$\prec$ -and its inverse $R^{-1}_{C,\prec}$ the \df{unranking function} for $C$ and~$\prec$. When the set -and the order are clear from the context, we will use plain~$R(x)$ and $R^{-1}(x)$. -Also, when $\prec$ is defined on a~superset~$C'$ of~$C$, we naturally extend $R_C(x)$ -to elements $x\in C'\setminus C$. - -\example -Let us consider the set $C_k=\{\0,\1\}^k$ of all binary strings of length~$k$ ordered -lexicographically. Then $R^{-1}(i)$ is the $i$-th smallest element of this set, that -is the number~$i$ written in binary and padded to~$k$ digits (i.e., $\(i)_k$ in the -notation of Section~\ref{ramds}). Obviously, $R(x)$ is the integer whose binary -representation is the string~$x$. - -%-------------------------------------------------------------------------------- - -\section{Ranking of permutations} -\id{pranksect} - -One of the most common ranking problems is ranking of permutations on the set~$[n]=\{1,2,\ldots,n\}$. -This is frequently used to create arrays indexed by permutations: for example in Ruskey's algorithm -for finding Hamilton cycles in Cayley graphs (see~\cite{ruskey:ham} and \cite{ruskey:hce}) -or when exploring state spaces of combinatorial puzzles like the Loyd's Fifteen \cite{ss:fifteen}. -Many other applications are surveyed by Critani et al.~\cite{critani:rau} and in -most cases, the time complexity of the whole algorithm is limited by the efficiency -of the (un)ranking functions. - -The permutations are usually ranked according to their lexicographic order. -In fact, an~arbitrary order is often sufficient if the ranks are used solely -for indexing of arrays. The lexicographic order however has an~additional advantage -of a~nice structure, which allows various operations on permutations to be -performed directly on their ranks. - -Na\"\i{}ve algorithms for lexicographic ranking require time $\Theta(n^2)$ in the -worst case \cite{reingold:catp} and even on average~\cite{liehe:raulow}. -This can be easily improved to $O(n\log n)$ by using either a binary search -tree to calculate inversions, or by a divide-and-conquer technique, or by clever -use of modular arithmetic (all three algorithms are described in Knuth -\cite{knuth:sas}). Myrvold and Ruskey \cite{myrvold:rank} mention further -improvements to $O(n\log n/\log \log n)$ by using the RAM data structures of Dietz -\cite{dietz:oal}. - -Linear time complexity was reached by Myrvold and Ruskey \cite{myrvold:rank} -for a~non-lexicographic order, which is defined locally by the history of the -data structure. -However, they leave the problem of lexicographic ranking open. -We will describe a~general procedure which, when combined with suitable -RAM data structures, yields a~linear-time algorithm for lexicographic -(un)ranking. - -\nota\id{brackets}% -We will view permutations on a~finite set $A\subseteq {\bb N}$ as ordered $\vert A\vert$-tuples -(in other words, arrays) containing every element of~$A$ exactly once. We will -use square brackets to index these tuples: $\pi=(\pi[1],\ldots,\pi[\vert A\vert])$, -and sub-tuples: $\pi[i\ldots j] = (\pi[i],\pi[i+1],\ldots,\pi[j])$. -The lexicographic ranking and unranking functions for the permutations on~$A$ -will be denoted by~$L(\pi,A)$ and $L^{-1}(i,A)$ respectively. - -\obs\id{permrec}% -Let us first observe that permutations have a simple recursive structure. -If we fix the first element $\pi[1]$ of a~permutation~$\pi$ on the set~$[n]$, the -elements $\pi[2], \ldots, \pi[n]$ form a~permutation on $[n]-\{\pi[1]\} = \{1,\ldots,\pi[1]-1,\pi[1]+1,\ldots,n\}$. -The lexicographic order of two permutations $\pi$ and~$\pi'$ on the original set is then determined -by $\pi[1]$ and $\pi'[1]$ and only if these elements are equal, it is decided -by the lexicographic comparison of permutations $\pi[2\ldots n]$ and $\pi'[2\ldots n]$. -Moreover, when we fix $\pi[1]$, all permutations on the smaller set occur exactly -once, so the rank of $\pi$ is $(\pi[1]-1)\cdot (n-1)!$ plus the rank of -$\pi[2\ldots n]$. - -This gives us a~reduction from (un)ranking of permutations on $[n]$ to (un)rank\-ing -of permutations on a $(n-1)$-element set, which suggests a straightforward -algorithm, but unfortunately this set is different from $[n-1]$ and it even -depends on the value of~$\pi[1]$. We could renumber the elements to get $[n-1]$, -but it would require linear time per iteration. To avoid this, we generalize the -problem to permutations on subsets of $[n]$. For a permutation $\pi$ on a~set -$A\subseteq [n]$ of size~$m$, similar reasoning gives a~simple formula: -$$ -L((\pi[1],\ldots,\pi[m]),A) = R_A(\pi[1]) \cdot (m-1)! + -L((\pi[2],\ldots,\pi[m]), A\setminus\{\pi[1]\}), -$$ -which uses the ranking function~$R_A$ for~$A$. This recursive formula immediately -translates to the following recursive algorithms for both ranking and unranking -(described for example in \cite{knuth:sas}): - -\alg $\(\pi,i,n,A)$: Compute the rank of a~permutation $\pi[i\ldots n]$ on~$A$. -\id{rankalg} -\algo -\:If $i\ge n$, return~0. -\:$a\=R_A(\pi[i])$. -\:$b\=\(\pi,i+1,n,A \setminus \{\pi[i]\})$. -\:Return $a\cdot(n-i)! + b$. -\endalgo - -\>We can call $\(\pi,1,n,[n])$ for ranking on~$[n]$, i.e., to calculate -$L(\pi,[n])$. - -\alg $\(j,i,n,A)$: Return an~array~$\pi$ such that $\pi[i\ldots n]$ is the $j$-th permutation on~$A$. -\id{unrankalg} -\algo -\:If $i>n$, return $(0,\ldots,0)$. -\:$x\=R^{-1}_A(\lfloor j/(n-i)! \rfloor)$. -\:$\pi\=\(j\bmod (n-i)!,i+1,n,A\setminus \{x\})$. -\:$\pi[i]\=x$. -\:Return~$\pi$. -\endalgo - -\>We can call $\(j,1,n,[n])$ to calculate $L^{-1}(j,[n])$. - -\paran{Representation of sets}% -The most time-consuming parts of the above algorithms are of course operations -on the set~$A$. If we store~$A$ in a~data structure of a~known time complexity, the complexity -of the whole algorithm is easy to calculate: - -\lemma\id{ranklemma}% -Suppose that there is a~data structure maintaining a~subset of~$[n]$ under a~sequence -of deletions, which supports ranking and unranking of elements, and that -the time complexity of a~single operation is at most~$t(n)$. -Then lexicographic ranking and unranking of permutations can be performed in time $\O(n\cdot t(n))$. - -If we store~$A$ in an~ordinary array, we have insertion and deletion in constant time, -but ranking and unranking in~$\O(n)$, so $t(n)=\O(n)$ and the algorithm is quadratic. -Binary search trees give $t(n)=\O(\log n)$. The data structure of Dietz \cite{dietz:oal} -improves it to $t(n)=O(\log n/\log \log n)$. In fact, all these variants are equivalent -to the classical algorithms based on inversion vectors, because at the time of processing~$\pi[i]$, -the value of $R_A(\pi[i])$ is exactly the number of elements forming inversions with~$\pi[i]$. - -To obtain linear time complexity, we will make use of the representation of -vectors by integers on the RAM as developed in Section~\ref{ramds}. We observe -that since the words of the RAM need to be able to hold integers as large as~$n!$, -the word size must be at least $\log n! = \Theta(n\log n)$. Therefore the whole -set~$A$ fits in~$\O(1)$ words and we get: - -\thmn{Lexicographic ranking of permutations} -When we order the permutations on the set~$[n]$ lexicographically, both ranking -and unranking can be performed on the RAM in time~$\O(n)$. - -\paran{The case of $k$-permutations}% -Our algorithm can be also generalized to lexicographic ranking of -\df{$k$-permutations,} that is of ordered $k$-tuples of distinct elements drawn from the set~$[n]$. -There are $n^{\underline k} = n\cdot(n-1)\cdot\ldots\cdot(n-k+1)$ -such $k$-permutations and they have a~recursive structure similar to the one of -the permutations. -Unfortunately, the ranks of $k$-permutations can be much smaller, so we can no -longer rely on the same data structure fitting in a constant number of word-sized integers. -For example, if $k=1$, the ranks are $\O(\log n)$-bit numbers, but the data -structure still requires $\Theta(n\log n)$ bits. - -We do a minor side step by remembering the complement of~$A$ instead, that is -the set of the at most~$k$ elements we have already seen. We will call this set~$H$ -(because it describes the ``holes'' in~$A$). Since $\Omega(k\log n)$ bits are needed -to represent the rank, the vector representation of~$H$ certainly fits in a~constant -number of words. When we translate the operations on~$A$ to operations on~$H$, -again stored as a~vector, we get: - -\thmn{Lexicographic ranking of $k$-permutations} -When we order the $k$-per\-mu\-ta\-tions on the set~$[n]$ lexicographically, both -ranking and unranking can be performed on the RAM in time~$\O(k)$. - -\section{Restricted permutations} - -Another interesting class of combinatorial objects that can be counted and -ranked are restricted permutations. An~archetypal member of this class are -permutations without a~fixed point, i.e., permutations~$\pi$ such that $\pi(i)\ne i$ -for all~$i$. These are also called \df{derangements} or \df{hatcheck permutations.} -We will present a~general (un)ranking method for any class of restricted -permutations and derive a~linear-time algorithm for the derangements from it. - -\defn\id{permnota}% -We will fix a~non-negative integer~$n$ and use ${\cal P}$ for the set of -all~permutations on~$[n]$. -A~\df{restriction graph} is a~bipartite graph~$G$ whose parts are two copies -of the set~$[n]$. A~permutation $\pi\in{\cal P}$ satisfies the restrictions -if $(i,\pi(i))$ is an~edge of~$G$ for every~$i$. - -\paran{Equivalent formulations}% -We will follow the path unthreaded by Kaplansky and Riordan -\cite{kaplansky:rooks} and charted by Stanley in \cite{stanley:econe}. -We will relate restricted permutations to placements of non-attacking -rooks on a~hollow chessboard. - -\defn -A~\df{board} is the grid $B=[n]\times [n]$. It consists of $n^2$ \df{squares.} -A~\df{trace} of a~permutation $\pi\in{\cal P}$ is the set of squares \hbox{$T(\pi)=\{ (i,\pi(i)) ; i\in[n] \}$.} - -\obs\id{rooksobs}% -The traces of permutations (and thus the permutations themselves) correspond -exactly to placements of $n$ rooks at the board in a~way such that the rooks do -not attack each other (i.e., there is at most one rook in every row and -likewise in every column; as there are $n$~rooks, there must be exactly one of them in -every row and column). When speaking about \df{rook placements,} we will always -mean non-attacking placements. - -Restricted permutations then correspond to placements of rooks on a~board with -some of the squares removed. The \df{holes} (missing squares) correspond to the -non-edges of~$G$, so $\pi\in{\cal P}$ satisfies the restrictions iff -$T(\pi)$ avoids the holes. - -Placements of~$n$ rooks (and therefore also restricted permutations) can be -also equated with perfect matchings in the restriction graph~$G$. The edges -of the matching correspond to the squares occupied by the rooks, the condition -that no two rooks share a~row nor column translates to the edges not touching -each other, and the use of exactly~$n$ rooks is equivalent to the matching -being perfect. - -There is also a~well-known correspondence between the perfect matchings -in a~bipartite graph and non-zero summands in the formula for the permanent -of the bipartite adjacency matrix~$M$ of the graph. This holds because the -non-zero summands are in one-to-one correspondence with the placements -of~$n$ rooks on the corresponding board. The number of restricted -permutations is therefore equal to the permanent of the matrix~$M$. - -The diversity of the characterizations of restricted permutations brings -both good and bad news. The good news is that we can use the -plethora of known results on bipartite matchings. Most importantly, we can efficiently -determine whether there exists at least one permutation satisfying a~given set of restrictions: - -\thm -There is an~algorithm which decides in time $\O(n^{1/2}\cdot m)$ whether there exists -a~permutation satisfying a~given restriction graph. The $n$ and~$m$ are the number -of vertices and edges of the restriction graph. - -The bad news is that computing the permanent is known to be~$\#\rm P$-complete even -for zero-one matrices (as proven by Valiant \cite{valiant:permanent}). -As a~ranking function for a~set of~matchings can be used to count all such -matchings, we obtain the following theorem: - -\thm\id{pcomplete}% -If there is a~polynomial-time algorithm for lexicographic ranking of permutations with -a~set of restrictions which is a~part of the input, then $\rm P=\#P$. - -However, the hardness of computing the permanent is the only obstacle. -We show that whenever we are given a~set of restrictions for which -the counting problem is easy (and it is also easy for subgraphs obtained -by deleting vertices), ranking is easy as well. The key will be once again -a~recursive structure, similar to the one we have seen in the case of plain -permutations in \ref{permrec}. We get: - -\thmn{Lexicographic ranking of restricted permutations} -Suppose that we have a~family of matrices ${\cal M}=\{M_1,M_2,\ldots\}$ such that $M_n\in \{0,1\}^{n\times n}$ -and it is possible to calculate the permanent of~$M'$ in time $\O(t(n))$ for every matrix $M'$ -obtained by deletion of rows and columns from~$M_n$. Then there exist algorithms -for ranking and unranking in ${\cal P}_{A,M_n}$ in time $\O(n^4 + n^2\cdot t(n))$ -if $M_n$ and an~$n$-element set~$A$ are given as a~part of the input. - -Our time bound for ranking of general restricted permutations section is obviously very coarse. -Its main purpose was to demonstrate that many special cases of the ranking problem can be indeed computed in polynomial time. -For most families of restriction matrices, we can do much better. These speedups are hard to state formally -in general (they depend on the structure of the matrices), but we demonstrate them on the -specific case of derangements. We show that each matrix can be sufficiently characterized -by two numbers: the order of the matrix and the number of zeroes in it. We find a~recurrent -formula for the permanent, based on these parameters, which we use to precalculate all -permanents in advance. When we plug it in the general algorithm, we get: - -\thmn{Ranking of derangements}% -For every~$n$, the derangements on the set~$[n]$ can be ranked and unranked according to the -lexicographic order in time~$\O(n)$ after spending $\O(n^2)$ on initialization of auxiliary tables. - -\schapter{Conclusions} - -We have seen the many facets of the minimum spanning tree problem. It has -turned out that while the major question of the existence of a~linear-time -MST algorithm is still open, backing off a~little bit in an~almost arbitrary -direction leads to a~linear solution. This includes classes of graphs with edge -density at least $\lambda_k(n)$ (the $k$-th row inverse of the Ackermann's function) for an~arbitrary fixed~$k$, -minor-closed classes, and graphs whose edge weights are -integers. Using randomness also helps, as does having the edges pre-sorted. - -If we do not know anything about the structure of the graph and we are only allowed -to compare the edge weights, we can use the Pettie's MST algorithm. -Its time complexity is guaranteed to be asymptotically optimal, -but we do not know what it really is --- the best what we have is -an~$\O(m\timesalpha(m,n))$ upper bound and the trivial $\Omega(m)$ lower bound. - -One thing we however know for sure. The algorithm runs on the weakest of our -computational models ---the Pointer Machine--- and its complexity is linear -in the minimum number of comparisons needed to decide the problem. We therefore -need not worry about the details of computational models, which have contributed -so much to the linear-time algorithms for our special cases. Instead, it is sufficient -to study the complexity of MST decision trees. However, not much is known about these trees so far. - -As for the dynamic algorithms, we have an~algorithm which maintains the minimum -spanning forest within poly-logarithmic time per operation. -The optimum complexity is once again undecided --- the known lower bounds are very far -from the upper ones. -The known algorithms run on the Pointer machine and we do not know if using a~stronger -model can help. - -For the ranking problems, the situation is completely different. We have shown -linear-time algorithms for three important problems of this kind. The techniques, -which we have used, seem to be applicable to other ranking problems. On the other -hand, ranking of general restricted permutations has turned out to balance on the -verge of $\#{\rm P}$-completeness. All our algorithms run -on the RAM model, which seems to be the only sensible choice for problems of -inherently arithmetic nature. While the unit-cost assumption on arithmetic operations -is not universally accepted, our results imply that the complexity of our algorithm -is dominated by the necessary arithmetics. - -Aside from the concrete problems we have solved, we have also built several algorithmic -techniques of general interest: the unification procedures using pointer-based -bucket sorting and the vector computations on the RAM. We hope that they will -be useful in many other algorithms. - -\schapter{Bibliography} - -\dumpbib - -\vfill\eject -\ifodd\pageno\else\hbox{}\fi - -\bye diff --git a/programs/n0.c b/programs/n0.c deleted file mode 100644 index 4327bd6..0000000 --- a/programs/n0.c +++ /dev/null @@ -1,156 +0,0 @@ -#include - -#define MAX 13 - -// Faktorial -int f(int n) -{ - static int ff[MAX] = { 1 }; - if (!ff[n]) - ff[n] = n*f(n-1); - return ff[n]; -} - -// Kombinacni cislo -int c(int n, int k) -{ - if (k > n/2) - k = n-k; - long long int r = 1; - for (int i=1; i<=k; i++) - { - r *= n--; - r /= i; - } - return r; -} - -// Satnarka -int s(int d) -{ - int r = 0; - int sg = 1; - for (int k=0; k<=d; k++) - { - r += sg*f(d)/f(k); - sg = -sg; - } - return r; -} - -// Castecne restrikce -int n0(int z, int d) -{ - static int nn[MAX][MAX]; - if (!nn[z][d]) - { - if (!z) - nn[z][d] = f(d); - else if (z == d) - nn[z][d] = s(d); - else - nn[z][d] = z*n0(z-1,d-1) + (d-z)*n0(z,d-1); - } - return nn[z][d]; -} - -// Vzorecek ze Stanleyho -int s0(int z, int d) -{ - int r = 0; - int p = 1; - for (int k=0; k<=z; k++) - { - r += p * f(d-k) * c(z,k); - p = -p; - } - return r; -} - -// Satnarciny pomerny -double alpha(int n) -{ - double x = 1; - int sg = -1; - for (int i=1; i<=n; i++) - { - x += sg*(1. / f(i)); - sg = -sg; - } - return x; -} - -int main(void) -{ - printf("Satnarka obema zpusoby:\n"); - for (int i=1; i= i) - printf("%d", n0(i, j)); - putchar('\t'); - } - putchar('\n'); - } - putchar('\n'); - - printf("Totez podle vzorecku ze Stanleyho:\n"); - for (int i=0; i= i) - printf("%d", s0(i, j)); - putchar('\t'); - } - putchar('\n'); - } - putchar('\n'); - - printf("Rozdily:\n"); - for (int i=0; i= i && i > 0) - printf("%d", n0(i-1,j)-n0(i,j)); - putchar('\t'); - } - putchar('\n'); - } - - printf("Pomery:\n"); - for (int i=0; i= i && i > 0) - { - double d = (double)n0(i-1,j)/(n0(i-1,j)-n0(i,j)); - printf("%2.4f", d); - } - putchar('\t'); - } - putchar('\n'); - } - - return 0; -} diff --git a/pubs.tex b/pubs.tex deleted file mode 100644 index 90faf9a..0000000 --- a/pubs.tex +++ /dev/null @@ -1,113 +0,0 @@ -\input macros.tex -\input fonts12.tex -\nopagenumbers - -\finaltrue -\hwobble=0mm -\advance\hsize by 1cm -\advance\vsize by 20pt - -\font\chapfont=csb14 at 16pt -\def\rawchapter#1{\vensure{0.5in}\bigskip\goodbreak -\leftline{\chapfont #1} -} - -\def\rawsection#1{\medskip\smallskip -\leftline{\secfont #1} -\nobreak -\smallskip -\nobreak -} - -\def\schapter#1{\chapter{#1}\medskip} - -\rawchapter{Publications of Martin Mare\v{s}} -\bigskip - -{ - -\def\bibitem[#1]#2#3\par{\:\eatspaces #3} -\def\em{\it} -\frenchspacing -\newcount\citecount -\def\newblock{\hskip .11em plus .33em minus .07em }% -\def\citelist{\numlist\singlecit\rightskip=0pt} -\def\singlecit{\global\advance\citecount by 1[\the\citecount]} -\hfuzz=4pt - -{\>\bo Research articles in journals and conference proceedings:} -\medskip - -\citelist - -\bibitem[Mar04]{mm:mst} -M.~Mare\v{s}. -\newblock {Two linear time algorithms for MST on minor closed graph classes}. -\newblock {\em {Archivum Mathematicum}}, 40:315--320. Masaryk University, Brno, - Czech Republic, 2004. - -\bibitem[MS07]{mm:rank} -M.~Mare\v{s} and M.~Straka. -\newblock Linear-time ranking of permutations. -\newblock In {\em Algorithms --- ESA 2007: 15th Annual European Symposium}, - volume 4698 of {\em {Lecture Notes in Computer Science}}, pages 187--193. - Springer Verlag, 2007. - -\bibitem[Mar07b]{mm:grading} -{M. Mare\v{s}}. -\newblock {Perspectives on Grading Systems}. -\newblock {\em Olympiads in Informatics}, 1:124--130. Institute of - Mathematics and Informatics, Vilnius, Lithuania, 2007. - -\endlist - -\>All three papers have been already published. - -\bigskip -{\>\bo Textbooks for university courses:} -\medskip - -\citelist - -\bibitem[Mar07]{mm:ga} -M.~Mare\v{s}. -\newblock {Krajinou grafov\'ych algoritm\accent23u (Through the Landscape of - Graph Algorithms)}. -\newblock ITI series 2007--330, Institut Teoretick\'e Informatiky, Praha, Czech - Republic, 2007. -\newblock -ISBN 978-80-239-9049-2. -\newblock In Czech. - -\endlist - -\bigskip - -\rawsection{Citations} - -\citelist - -%S. Tazari and M. Müller-Hannemann -%Shortest Paths in Linear Time on Minor-Closed Graph Classes with an Application to Steiner Tree Approximation (abstract) -%submitted for publication, 2007. - -\bibitem[HW07]{hochstein:maxflow} -J.~M. Hochstein and K.~Weihe. -\newblock {Maximum $s$-$t$-flow with $k$ crossings in $\O(k^3n \log n)$ time}. -\newblock In {\em SODA 2007: Proceedings of the 18th annual ACM-SIAM symposium - on Discrete algorithms}, pages 843--847, 2007. -\newblock Cites~[1]. - -\bibitem[MHT07]{tazari:mcgc} -M.~M\"uller-Hannemann and S.~Tazari. -\newblock {Handling Proper Minor-Closed Graph Classes in Linear Time: Shortest - Paths and 2-Approximate Steiner Trees}. -\newblock Tech Report 2007/5, University of Halle-Wittenberg, Institute of - Computer Science, 2007. -\newblock Cites~[1]. - -\endlist - -} - -\bye diff --git a/slides/Makefile b/slides/Makefile deleted file mode 100644 index 67ad505..0000000 --- a/slides/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -all: slides.pdf - -slides.pdf: slides.tex - pdflatex slides.tex - -clean: - rm -f *~ *.{aux,log,nav,out,pdf,snm,toc} diff --git a/slides/brum2.png b/slides/brum2.png deleted file mode 100644 index 3b4fb98642e39b95eb517aeddf27a83f3c3d5b27..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 101760 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%0D&49A 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 diff --git a/slides/slides.tex b/slides/slides.tex deleted file mode 100644 index b0bacc8..0000000 --- a/slides/slides.tex +++ /dev/null @@ -1,364 +0,0 @@ -\documentclass{beamer} -\usepackage[latin2]{inputenc} -\usepackage{palatino} -\usetheme{Warsaw} -\title[Graph Algorithms]{Graph Algorithms\\Spanning Trees and Ranking} -\author[Martin Mare¹]{Martin Mare¹\\\texttt{mares@kam.mff.cuni.cz}} -\institute{Department of Applied Mathematics\\MFF UK Praha} -\date{2008} -\begin{document} -\setbeamertemplate{navigation symbols}{} -\setbeamerfont{title page}{family=\rmfamily} - -\def\[#1]{\hskip0.3em{\color{violet} [#1]}} -\def\O{{\cal O}} - -\begin{frame} -\titlepage -\end{frame} - -\begin{frame}{The Minimum Spanning Tree Problem} - -{\bf 1. Minimum Spanning Tree Problem:} - -\begin{itemize} -\item Given a~weighted undirected graph,\\ - what is its lightest spanning tree? -\item In fact, a~linear order on edges is sufficient. -\item Efficient solutions are very old \[Borùvka 1926] -\item A~long progression of faster and faster algorithms. -\item Currently very close to linear time, but still not there. -\end{itemize} - -\end{frame} - -\begin{frame}{The Ranking Problems} - -{\bf 2. Ranking of Combinatorial Structures:} - -\begin{itemize} -\item We are given a~set~$C$ of objects with a~linear order $\prec$. -\item {\bf Ranking function $R_\prec(x)$:} how many objects precede~$x$? -\item {\bf Unranking function $R^{-1}_\prec(i)$:} what is the $i$-th object? -\end{itemize} - -\pause - -\begin{example}[toy] -$C=\{0,1\}^n$ with lexicographic order - -\pause -$R$ = conversion from binary\\ -$R^{-1}$ = conversion to binary -\end{example} - -\pause -\begin{example}[a~real one] -$C=$ set of all permutations on $\{1,\ldots,n\}$ -\end{example} - -\pause -How to compute the (un)ranking function efficiently? - -For permutations, an $\O(n\log n)$ algorithm was known \[folklore]. - -We will show how to do that in $\O(n)$. - -\end{frame} - -\begin{frame}{Models of computation: RAM} - -As we approach linear time, we must specify the model. - -~ - -{\bf 1. The Random Access Machine (RAM):} - -\begin{itemize} -\item Works with integers -\item Memory: an array of integers indexed by integers -\end{itemize} - -~ -\pause - -Many variants exist, we will use the {\bf Word-RAM:} - -\begin{itemize} -\item Machine words of $W$ bits -\item The ``C operations'': arithmetics, bitwise logical op's -\item Unit cost -\item We know that $W\ge\log_2 \vert \hbox{input} \vert$ -\end{itemize} - -\end{frame} - -\begin{frame}{Models of computation: PM} - -{\bf 2. The Pointer Machine (PM):} - -\begin{itemize} -\item Memory cells accessed via pointers -\item Each cell contains $\O(1)$ pointers and $\O(1)$ symbols -\item Operates only on pointers and symbols -\end{itemize} - -~ -\pause - -\begin{beamerboxesrounded}[upper=block title example,shadow=true]{Key differences} -\begin{itemize} -\item PM has no arrays, we can emulate them in $\O(\log n)$ time. -\item PM has no arithmetics. -\end{itemize} -\end{beamerboxesrounded} - -~ - -We can emulate PM on RAM with constant slowdown. - -Emulation of RAM on PM is more expensive. - -\end{frame} - -\begin{frame}{PM Techniques} - -{\bf Bucket Sorting} does not need arrays. - -~ - -Interesting consequences: - -\begin{itemize} -\item Flattening of multigraphs in $\O(m+n)$ -\item Unification of sequences in $\O(n+\sum_i\ell_i+\vert\Sigma\vert)$ -\item (Sub)tree isomorphism in $\O(n)$ simplified \[M. 2008] -\item Batched graph computations \[Buchsbaum et al.~1998] -\end{itemize} - -\end{frame} - -\begin{frame}{RAM Techniques} - -We can use RAM as a vector machine: - -~ - -\begin{example}[parallel search] -\def\sep{\;{\color{brown}0}} -\def\seq{\;{\color{brown}1}} -\def\sez{\;{\color{red}0}} -We can encode the vector $(1,5,3,0)$ with 3-bit fields as: -\begin{center} -\sep001\sep101\sep011\sep000 -\end{center} -And then search for 3 by: - -\begin{center} -\begin{tabular}{rcl} - &\seq001\seq101\seq011\seq000 & $(1,5,3,0)$ \\ -{\sc xor} &\sep011\sep011\sep011\sep011 & $(3,3,3,3)$ \\ -\hline - &\seq010\seq110\seq000\seq011 \\ -$-$ &\sep001\sep001\sep001\sep001 & $(1,1,1,1)$ \\ -\hline - &\seq001\seq101\sez111\seq010 \\ -{\sc and} &\seq000\seq000\seq000\seq000 \\ -\hline - &\seq000\seq000\sez000\seq000 \\ -\end{tabular} -\end{center} -\end{example} - -\end{frame} - -\begin{frame}{RAM Data Structures} - -We can translate vector operations to $\O(1)$ RAM instructions - -\smallskip - -\dots\ as long as the vector fits in $\O(1)$ words. - -~ - -We can build ``small'' data structures operating in $\O(1)$ time: - -\begin{itemize} -\item Sets -\item Ordered sets with ranking -\item ``Small'' heaps of ``large'' integers \[Fredman \& Willard 1990] -\end{itemize} - -\end{frame} - -\begin{frame}{Minimum Spanning Trees} -Algorithms for Minimum Spanning Trees: - -\begin{itemize} -\item Classical algorithms \[Borùvka, Jarník-Prim, Kruskal] -\item Contractive: $\O(m\log n)$ using flattening on the PM \\ - (lower bound \[M.]) -\item Iterated: $\O(m\,\beta(m,n))$ \[Fredman \& Tarjan~1987] \\ - where $\beta(m,n) = \min\{ k: \log_2^{(k)} n \le m/n \}$ -\item Even better: $\O(m\,\alpha(m,n))$ using {\it soft heaps}\hfil\break\[Chazelle 1998, Pettie 1999] -\item MST verification: $\O(m)$ on RAM \[King 1997, M. 2008] -\item Randomized: $\O(m)$ expected on RAM \[Karger et al.~1995] -\end{itemize} -\end{frame} - -\begin{frame}{MST -- Special cases} - -Cases for which we have an $\O(m)$ algorithm: - -~ - -Special graph structure: - -\begin{itemize} -\item Planar graphs \[Tarjan 1976, Matsui 1995, M. 2004] (PM) -\item Minor-closed classes \[Tarjan 1983, M. 2004] (PM) -\item Dense graphs (by many of the general PM algorithms) -\end{itemize} - -~ -\pause - -Or we can assume more about weights: - -\begin{itemize} -\item $\O(1)$ different weights \[folklore] (PM) -\item Integer weights \[Fredman \& Willard 1990] (RAM) -\item Sorted weights (RAM) -\end{itemize} - -\end{frame} - -\begin{frame}{MST -- Optimality} - -There is a~provably optimal comparison-based algorithm \\\[Pettie \& Ramachandran 2002] - -~ - -However, there is a catch\alt<2->{:}{ \dots} \pause Nobody knows its complexity. - -~ - -We know that it is $\O({\cal T}(m,n))$ where ${\cal T}(m,n)$ is the depth -of the optimum MST decision tree. Any other algorithm provides an upper bound. - -\pause -~ - -\begin{corollary} -It runs on the PM, so we know that if there is a~linear-time algorithm, -it does not need any special RAM data structures. (They can however -help us to find it.) -\end{corollary} - -\end{frame} - -\begin{frame}{MST -- Dynamic algorithms} - -Sometimes, we need to find the MST of a~changing graph. \\ -We insert/delete edges, the structure responds with $\O(1)$ -modifications of the MST. - -\begin{itemize} -\item Unweighted cases, similar to dynamic connectivity: - \begin{itemize} - \item Incremental: $\O(\alpha(n))$ \[Tarjan 1975] - \item Fully dynamic: $\O(\log^2 n)$ \[Holm et al.~2001] - \end{itemize} -\pause -\item Weighted cases are harder: - \begin{itemize} - \item Decremental: $\O(\log^2 n)$ \[Holm et al.~2001] - \item Fully dynamic: $\O(\log^4 n)$ \[Holm et al.~2001] - \item Only~$C$ weights: $\O(C\log^2 n)$ \[M. 2008] - \end{itemize} -\pause -\item $K$ smallest spanning trees: - \begin{itemize} - \item Simple: $\O(T_{MST} + Km)$ \[Katoh et al.~1981, M.~2008] - \item Small~$K$: $\O(T_{MST} + \min(K^2, Km + K\log K))$ \[Eppst.~1992] - \item Faster: $\O(T_{MST} + \min(K^{3/2}, Km^{1/2}))$ \[Frederickson 1997] - \end{itemize} -\end{itemize} - -\end{frame} - -\begin{frame}{Back to Ranking} - -Ranking of permutations on the RAM: \[M. \& Straka 2007] - -\begin{itemize} -\item We need a DS for the subsets of $\{1,\ldots,n\}$ with ranking -\item The result can be $n!$ $\Rightarrow$ word size is $\Omega(n\log n)$ bits -\item We can represent the subsets as RAM vectors -\item This gives us an~$\O(n)$ time algorithm for (un)ranking -\end{itemize} - -~ - -Easily extendable to $k$-permutations, also in $\O(n)$ - -\end{frame} - -\begin{frame}{Restricted permutations} - -For restricted permutations (e.g., derangements): \[M. 2008] - -\begin{itemize} -\item Describe restrictions by a~bipartite graph -\item Existence of permutation reduces to network flows -\item The ranking function can be used to calculate permanents,\\ - so it is $\#\rm P$-complete -\item However, this is the only obstacle. Calculating $\O(n)$ - sub-permanents is sufficient. -\item For derangements, we have achieved $\O(n)$ time after $\O(n^2)$ time - preprocessing. -\end{itemize} - -\end{frame} - -\begin{frame}{Summary} - -Summary:\\ - -\begin{itemize} -\item Low-level algorithmic techniques on RAM and PM -\item Generalized pointer-based sorting and RAM vectors -\item Applied to a~variety of problems: - \begin{itemize} - \item A~short linear-time tree isomorphism algorithm - \item A~linear-time algorithm for MST on minor-closed classes - \item Corrected and simplified MST verification - \item Dynamic MST with small weights - \item {\it Ranking and unranking of permutations} - \end{itemize} -\item Also: - \begin{itemize} - \item A~lower bound for the Contractive Borùvka's algorithm - \item Simplified soft-heaps - \end{itemize} -\end{itemize} - -\end{frame} - -\begin{frame}{Good Bye} - -\bigskip - -\centerline{\sc\huge The End} - -\bigskip - -\begin{figure} -\pgfdeclareimage[width=0.3\hsize]{brum}{brum2.png} -\pgfuseimage{brum} -\end{figure} - -\end{frame} - -\end{document} -- 2.39.2