]> mj.ucw.cz Git - ga.git/commitdiff
Nova kapitola o APSP: Floyd-Warshall a regularni vyrazy
authorMartin Mares <mj@ucw.cz>
Sun, 16 Jan 2011 21:45:17 +0000 (22:45 +0100)
committerMartin Mares <mj@ucw.cz>
Sun, 16 Jan 2011 21:45:17 +0000 (22:45 +0100)
14-floyd/14-floyd.tex [new file with mode: 0644]
14-floyd/Makefile [new file with mode: 0644]

diff --git a/14-floyd/14-floyd.tex b/14-floyd/14-floyd.tex
new file mode 100644 (file)
index 0000000..f3371b3
--- /dev/null
@@ -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 (file)
index 0000000..292d89c
--- /dev/null
@@ -0,0 +1,3 @@
+P=14-floyd
+
+include ../Makerules