From: Martin Mares Date: Sun, 16 Jan 2011 21:45:17 +0000 (+0100) Subject: Nova kapitola o APSP: Floyd-Warshall a regularni vyrazy X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=47208e22a417bf7bd4bb27db038e131415ec1382;p=ga.git Nova kapitola o APSP: Floyd-Warshall a regularni vyrazy --- diff --git a/14-floyd/14-floyd.tex b/14-floyd/14-floyd.tex new file mode 100644 index 0000000..f3371b3 --- /dev/null +++ b/14-floyd/14-floyd.tex @@ -0,0 +1,167 @@ +\input ../sgr.tex + +\def\alt{\mathop{\vert}} + +\prednaska{13}{Nejkrat¹í cesty: Maticové metody}{} + +V~pøedchozí kapitole jsme se zabývali algoritmy pro hledání nejkrat¹ích +cest z~daného poèáteèního vrcholu. Nyní se zamìøíme na výpoèet celé +metriky grafu, tedy matice vzdáleností, která pro ka¾dou dvojici vrcholù +obsahuje délku nejkrat¹í cesty mezi nimi. + +Jeden zpùsob se ihned nabízí: postupnì spustit Dijkstrùv algoritmus pro v¹echny +mo¾né volby poèáteèního vrcholu, pøípadnì se pøed tím je¹tì pomocí potenciálù +zbavit záporných hran. Tak dosáhneme èasové slo¾itosti $\O(mn + n^2\log n)$, +co¾ je pro øídké grafy nejlep¹í známý výsledek -- jen $\O(\log n)$-krát +pomalej¹í, ne¾ je velikost výstupu. + +Pro husté grafy obvykle pracují rychleji algoritmy zalo¾ené na maticích a zejména +na jejich násobení. Nìkolik takových si nyní pøedvedeme. Vrcholy grafu budou +v¾dy oèíslované èísly 1 a¾~$n$ a graf doplníme na úplný, pøièem¾ hrany, které +pùvodnì neexistovaly, obdr¾í délku $+\infty$. + +\h{Floydùv-Warshallùv algoritmus} + +Zaènìme algoritmem, který nezávisle na sobì objevili Floyd a Warshall. +Funguje pro libovolný orientovaný graf bez záporných cyklù. + +Oznaème $D^k_{ij}$ délku nejkrat¹í cesty z~vrcholu~$i$ do vrcholu~$j$ pøes +vrcholy 1 a¾~$k$ (tím myslíme, ¾e v¹echny vnitøní vrcholy cesty le¾í v~mno¾inì $\{1,\ldots,k\}$). +Jako obvykle polo¾íme $D^k_{ij}=+\infty$, pokud ¾ádná taková cesta neexistuje. +Pak platí: +$$\eqalign{ +D^0_{ij} &= \hbox{délka hrany $ij$,} \cr +D^n_{ij} &= \hbox{vzdálenost z~$i$ do~$j$,} \cr +D^k_{ij} &= \min( D^{k-1}_ij, D^{k-1}_{ik} + D^{k-1}_{kj} ). \cr +}$$ +První dvì rovnosti dostaneme pøímo z~definice. Tøetí rovnost dostaneme rozdìlením +cest z~$i$ do~$j$ pøes 1 a¾~$k$ na ty, které se vrcholu~$k$ vyhnou (a~jsou tedy +cestami pøes 1 a¾~$k-1$), a ty, které ho pou¾ijí -- ka¾dou takovou mù¾eme slo¾it +z~cesty z~$i$ do~$k$ a cesty z~$k$ do~$j$, obojí pøes 1 a¾~$k-1$. + +Zbývá vyøe¹it jednu malièkost: slo¾ením cesty z~$i$ do~$k$ s~cestou z~$k$ do~$j$ +nemusí nutnì vzniknout cesta, proto¾e se nìjaký vrchol mù¾e opakovat. V~grafech +bez záporných cyklù nicménì takový sled nemù¾e být krat¹í ne¾ nejkrat¹í cesta, +tak¾e tím fale¹né øe¹ení nevyrobíme. (Pøesnìji: ze sledu $i\alpha v\beta k\gamma v\delta j$, +kde $v\not\in\beta,\gamma$, mù¾eme vypu¹tìním èásti $v\beta k\gamma v$ nezáporné +délky získat sled z~$i$ do~$j$ pøes 1 a¾~$k-1$, jeho¾ délka nemù¾e být men¹í +ne¾~$D^{k-1}{ij}$.) + +Samotný algoritmus pak postupnì poèítá matice $D^0, D^1, \ldots, D^n$: + +\algo +\:$D^0 \leftarrow \hbox{matice délek hran}$ +\:Pro $k=1,\ldots,n$: +\::Pro $i,j=1,\ldots,n$: +\:::$D^k_{ij} = \min( D^{k-1}_ij, D^{k-1}_{ik} + D^{k-1}_{kj} )$. +\:$\hbox{Matice vzdáleností} \leftarrow D^n.$ +\endalgo + +Èasová slo¾itost tohoto algoritmu èiní $\Theta(n^3)$. Kubickou prostorovou +slo¾itost mù¾eme snadno sní¾it na~kvadratickou: Buï si uvìdomíme, ¾e v~ka¾dém +okam¾iku potøebujeme jen aktuální matici~$D^k$ a pøedchozí~$D^{k-1}$. Anebo +nahlédneme, ¾e mù¾eme $D^{k-1}$ na~$D^k$ pøepisovat na místì. U~hodnot $D_{ik}$ +a~$D_{kj}$ je toti¾ podle definice stará i nová hodnota stejná. Algoritmu tedy +staèí $\Theta(n^2)$ pamìti. + +\h{Regulární výrazy} + +Pøedchozí algoritmus lze zajímavì zobecnit, toti¾ tak, aby pro ka¾dou dvojici +vrcholù sestrojil vhodnou reprezentaci mno¾iny v¹ech sledù vedoucích mezi touto +dvojicí. Tato reprezentace bude velice podobná regulárním výrazùm známým +z~teorie automatù. Zadaný orientovaný graf pøitom mù¾e obsahovat i smyèky +a násobné hrany. + +\s{Definice:} {\I Sledový regulární výraz} pro vrcholy $u$ a~$v$ (zkrácenì +{\I $uv$-výraz}) kóduje mno¾inu sledù z~vrcholu~$u$ do vrcholu~$v$. Mno¾inu +kódovanou výrazem~$\psi$ budeme znaèit $S(\psi)$. Ka¾dý $uv$-výraz má jeden +z~tìchto tvarù: + +\itemize\ibull +\:$\emptyset$ -- prázdná mno¾ina sledù, +\:$e$ -- identifikátor nìkteré hrany z~$u$ do~$v$, +\:$\alpha\alt\beta$ (kde $\alpha$ i $\beta$ jsou $uv$-výrazy) -- +{\I sjednocení:} $S(\alpha\alt\beta) = S(\alpha) \cup S(\beta)$, +\:$\alpha\beta$ (kde $\alpha$ je $uw$-výraz a $\beta$ je $wv$-výraz pro nìjaké~$w$) -- +{\I zøetìzení:} $S(\alpha\beta)$ je mno¾ina v¹ech sledù, které vzniknou +napojením nìjakého sledu z~$S(\beta)$ za nìjaký sled z~$S(\alpha)$, +\endlist + +\>Pokud $u=v$, pak navíc: +\itemize\ibull +\:$\varepsilon$ -- mno¾ina obsahující pouze sled nulové délky, +\:$\alpha^*$ (kde $\alpha$ je $uu$-výraz) -- {\I iterace:} +$\alpha^* = \varepsilon \alt \alpha \alt \alpha\alpha \alt \alpha\alpha\alpha \alt \ldots$ +\endlist +\>Operace sjednocení a zøetìzení jsou asociativní, tak¾e je obvykle nebudeme +závorkovat; operace sjednocení má ve~výrazech ni¾¹í prioritu ne¾ zøetìzení. + +Pro ka¾dou dvojici vrcholù $i$,~$j$ nyní budeme hledat výraz $R_{ij}$ popisující +v¹echny sledy z~$i$ do~$j$. Podobnì jako u~Floydova-Warshallova algoritmu zavedeme +$R^k_{ij}$ coby výraz popisující sledy z~$i$ do~$j$ pøes 1 a¾~$k$ a nahlédneme, +¾e platí: +$$\eqalign{ +R^0_{ij} &= \hbox{mno¾ina v¹ech hran z~$i$ do~$j$}, \cr +R^n_{ij} &= \hbox{hledané $R_{ij}$}, \cr +R^k_{ij} &= R^{k-1}_{ij} \alt R^{k-1}_{ik}(R^{k-1}_{kk})^*R^{k-1}_{kj}. \cr +}$$ +První dvì rovnosti opìt dostaneme pøímo z~definice (mno¾inu v¹ech hran zapí¹eme +buï jako prázdnou nebo ji vytvoøíme sjednocováním z~jednoprvkových mno¾in). Tøetí +rovnost vychází z~toho, ¾e ka¾dý sled z~$i$ do~$j$ buï neobsahuje~$k$, nebo ho +mù¾eme rozdìlit na~èásti mezi jednotlivými náv¹tìvami vrcholu~$k$. + +Algoritmus tedy bude postupnì budovat matice $R^0, R^1, \ldots, R^n$ podle tìchto +pravidel. Provedeme pøi tom $\Theta(n^3)$ operací, ov¹em s~výrazy, jejich¾ délka +mù¾e být a¾ øádovì~$4^n$. Radìji ne¾ jako øetìzce je budeme ukládat v~podobì +acyklických orientovaných grafù: vrcholy budou operace, hrany je budou pøipojovat +k~operandùm. + +K~pøímému pou¾ití se takový exponenciálnì dlouhý výraz hodí málokdy, ale mù¾e +nám pomoci odpovídat na rùzné otázky týkající se sledù s~danými koncovými vrcholy. +Máme-li nìjakou funkci~$f$ pøiøazující hodnoty mno¾inám sledù kódovaným sledovými +výrazy, staèí umìt vyhodnotit: +\itemize\ibull +\:výsledek pro triviální výrazy $f(\emptyset)$, $f(\varepsilon)$ a $f(e)$ pro hranu~$e$, +\:hodnoty $f(\alpha\alt\beta)$, $f(\alpha\beta)$ a $f(\alpha^*)$, známe-li ji¾ $f(\alpha)$ a $f(\beta)$. +\endlist +\>Pro výpoèet v¹ech $f(R_{ij})$ nám pak staèí $\Theta(n^3)$ vyhodnocení funkce~$f$. + +\s{Pøíklady:} + +\>{\I Nejkrat¹í sled:} +$$\eqalign{ +f(\emptyset)&=+\infty \cr +f(\varepsilon)&=0 \cr +f(e)&=\ell(e) \hbox{\quad (délka hrany)} \cr +f(\alpha\alt\beta) &= \min(f(\alpha),f(\beta)) \cr +f(\alpha\beta) &= f(\alpha) + f(\beta) \cr +f(\alpha^*) &= \cases{0 & \hbox{pro $f(\alpha)\ge 0$} \cr -\infty & \hbox{pro $f(\alpha)<0$} \cr} \cr +}$$ +(Pokud pøedpokládáme, ¾e v~grafu nejsou záporné cykly, je $f(\alpha^*)$ v¾dy nulové +a dostaneme pøesnì Floydùv-Warshallùv algoritmus.) + +\>{\I Nej¹ir¹í cesta} (hranám jsou pøiøazeny ¹íøky, ¹íøka cesty je minimum z~¹íøek hran): +$$\eqalign{ +f(\emptyset)&=0 \cr +f(\varepsilon)&=\infty \cr +f(e)&=w(e) \hbox{\quad (¹íøka hrany)} \cr +f(\alpha\alt\beta) &= \max(f(\alpha),f(\beta)) \cr +f(\alpha\beta) &= \min(f(\alpha),f(\beta)) \cr +f(\alpha^*) &= \infty \cr +}$$ + +\>{\I Pøevod koneèného automatu na regulární výraz:} Vrcholy multigrafu budou odpovídat +stavùm automatu, hrany mo¾ným pøechodùm mezi stavy. Ka¾dou hranu ohodnotíme symbolem +abecedy, po jeho¾ pøeètení automat pøechod provede. Funkce~$f$ pak pøiøadí $uv$-výrazu~$\psi$ +regulární výraz popisující mno¾inu v¹ech øetìzcù, po jejich¾ pøeètení automat pøejde +ze~stavu~$u$ do stavu~$v$ po pøechodech z~mno¾iny $S(\psi)$. Vyhodnocování funkce~$f$ +odpovídá pøímoèarým operacím s~øetìzci. + +\h{Dosa¾itelnost pomocí násobení matic} + +\h{Seidelùv algoritmus} + +\h{Rozdìl a panuj} + +\references +\bye diff --git a/14-floyd/Makefile b/14-floyd/Makefile new file mode 100644 index 0000000..292d89c --- /dev/null +++ b/14-floyd/Makefile @@ -0,0 +1,3 @@ +P=14-floyd + +include ../Makerules