From: Martin Mares Date: Tue, 24 May 2011 15:46:21 +0000 (+0200) Subject: Grafy: Dopsano DFS X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=789301f3844fbb9eb3e7f8fd9021499ceb24962d;p=ads1.git Grafy: Dopsano DFS --- diff --git a/3-grafy/3-grafy.tex b/3-grafy/3-grafy.tex index 4031243..e5f34f2 100644 --- a/3-grafy/3-grafy.tex +++ b/3-grafy/3-grafy.tex @@ -1,6 +1,6 @@ \input ../lecnotes.tex -\prednaska{3}{Prohledání do~¹íøky a do~hloubky}{} +\prednaska{3}{Prohledání grafù}{} \h{Prohledání do~¹íøky {\I Breadth-First Search -- BFS} } @@ -239,73 +239,89 @@ To, co jsme o~BFS zjistili, m \:strom nejkrat¹ích cest z~$v_0$ \endlist -\>Prohledávání do~¹íøky ale není jediný algoritmus, který nìjak systematicky prochází graf. Jak u¾ název kapitoly napovídá, budeme se zabývat je¹tì druhým algoritmem, prohledáváním do~hloubky. Podívejme se, jak bude vypadat \dots +\>Prohledávání do~¹íøky ale není jediný algoritmus, který nìjak systematicky +prochází graf. Jak u¾ název kapitoly napovídá, budeme se zabývat je¹tì druhým +algoritmem, prohledáváním do~hloubky. Podívejme se, jak bude vypadat \dots \h{Prohledávání do~hloubky {\I Depth-First Search -- DFS }} -Tento algoritmus neprochází graf ve~vlnì jako BFS, nýbr¾ ho prochází -rekurzivnì. V¾dy se zanoøí co nejhloubìji a¾ do~listu a pak se o~kus vrátí -a opìt se sna¾í zanoøit. Vrcholy, ve kterých u¾ byl, ignoruje. +Tento algoritmus neprochází graf ve~vlnì jako BFS, nýbr¾ rekurzivnì. V¾dy se +zanoøí co nejhloubìji a¾ do~listu a pak se o~kus vrátí a opìt se sna¾í zanoøit. +Vrcholy, ve kterých u¾ byl, ignoruje. Opìt uva¾me nejdøíve graf orientovaný. Následnì si uká¾eme, ¾e v~neorientovaném grafu budou pouze malé zmìny. -Budeme pou¾ívat podobné znaèení jako u~BFS. V~poli $Z$ si budeme pamatovat, zda jsme vrchol ji¾ nav¹tívili (hodnota 1), nebo ne (hodnota 0). Navíc promìnná~$T$ bude znaèit dobu bìhu algoritmu - tedy jakési \uv{hodiny}. Pøi ka¾dém nalezení nového vrcholu èi jeho opu¹tìní tuto promìnnou zvý¹íme o~1. Do~polí $\$ a $\$ si budeme ukládat èas (prvního) nalezení a opu¹tìní vrcholu. +Budeme pou¾ívat podobné znaèení jako u~BFS. V~poli $Z$ si budeme pamatovat, zda +jsme vrchol ji¾ nav¹tívili (hodnota 1), nebo ne (hodnota 0). Aby se nám algoritmus +lépe analyzoval, zavedeme promìnnou~$T$, která bude fungovat jako hodiny -- v~ka¾dém +kroku algoritmu se zvìt¹í o~jednièku. Do~polí $\$ a $\$ si budeme ukládat èas +prvního a posledního prùchodu vrcholem. \s{Algoritmus:} \algo -\: inicializace: $Z[*] \leftarrow 0, T \leftarrow 1, \[*] \leftarrow ?, \[*] \leftarrow ?$ -\: $DFS(v): Z[v] \leftarrow 1, \[v] \leftarrow T|++|$ -\:: Pro $w$: $vw \in E(G)$: -\::: Pokud $Z[w]=0 \Rightarrow DFS(w)$ -\:: $out[v] \leftarrow T|++|$ +\:Inicializace: $Z[*] \leftarrow 0, T \leftarrow 1, \[*] \leftarrow ?, \[*] \leftarrow ?$ +\:$\(v)$: +\::$Z[v] \leftarrow 1$, $\[v] \leftarrow T$, $T\leftarrow T+1$ +\::Pro $w$: $vw \in E(G)$: +\:::Pokud $Z[w]=0$, zavoláme $\(w)$ +\::$out[v] \leftarrow T$, $T\leftarrow T+1$ \endalgo \s {Vìta:} DFS($v_0$) v~èase $\Theta(m+n)$ oznaèí právì v¹echny vrcholy dosa¾itelné z~$v_0$. \proof -Nejdøíve je potøeba dokázat, ¾e pokud je vrchol $v$ dosa¾itelný z~vrcholu $v_0$, tak jej DFS oznaèí. Dùkaz bude podobný jako u~BFS. +Korektnost doká¾eme stejným argumentem, jako u~BFS. -V analýze èasové slo¾itosti si pak opìt uvìdomíme, ¾e algoritmus vezme ka¾dý vrchol i hranu do~ruky právì jednou, tak¾e èasová slo¾itost bude $\Theta(n + m)$. +V~analýze èasové slo¾itosti si pak opìt uvìdomíme, ¾e algoritmus zavoláme +na~ka¾dý vrchol nejvý¹e jednou (pak u¾ je oznaèený) a zpracováním vrcholu +strávíme èas lineární v~poètu hran, které z~nìj vedou. Celkem tedy prozkoumáme +ka¾dou hranu nejvý¹e jednou a strávíme tím konstantní èas. \qed -\figure{img5_dfso.eps}{Graf a znázornìní prùbìhu DFS s~jednotlivými hranami:}{\epsfxsize} +Vyzkou¹ejme si DFS na grafu z~následujícího obrázku: -Mù¾eme si v¹imnout, ¾e jak DFS prochází graf, rozdìluje hrany do~4 skupin: hrany {\I stromové, zpìtné, dopøedné a pøíèné}. +\figure{dfs.eps}{Znázornìní prùbìhu DFS a typù hran}{\epsfxsize} -Jedinì {\I stromové} hrany jsou takové, ¾e se po~nich DFS opravdu vydá. Vedou toti¾ do~vrcholu, který nebyl dosud objeven. V~ukázkovém grafu to jsou hrany: $\{(A \rightarrow B), (B \rightarrow C), (B \rightarrow D)\}$. +Graf je reprezentován tak, ¾e v~ka¾dém vrcholu jsou hrany uspoøádány zleva doprava. +Èísla u~vrcholù ukazují jejich \ a \. -Pokud algoritmus objeví z~vrcholu $v$ hranu do~ji¾ døíve nav¹tíveného vrcholu $w$ a zároveò platí, ¾e $w$ je ve~stejném podstromu jako $v$, tak nazveme hranu $vw$ {\I zpìtnou}. Pro rozpoznání je dùle¾ité, ¾e vrchol $w$ byl ji¾ objeven, ale je¹tì ne opu¹tìn. V~ukázkovém grafu se jedná o hranu: $(C \rightarrow A)$. +Mù¾eme si v¹imnout, ¾e k~rùzným hranám se DFS chová rùznì. Po~nìkterých projde, +jiné vedou do u¾ prozkoumaných vrcholù, ale nìkdy do~takových, ze~kterých jsme +se je¹tì nevrátili, jindy do u¾ zpracovaných. Za chvíli uvidíme, ¾e mohou nastat +ètyøi rùzné situace. Nejsnáze se poznávají podle hodnot \ a \. -Kdy¾ pøi prohledávání sousedù vrcholu $v$ narazíme na~vrchol $w$, který jsme ji¾ nav¹tívili, a to v~podstromì vrcholu $v$, tak nazveme hranu $vw$ {\I dopøednou}, nebo» vede z~$v$ do~jeho potomka. Platí tedy, ¾e jsme nejdøíve objevili vrchol $v$, potom vrchol $w$, pak jsme vrchol $w$ opustili a nyní jsme na~nìj znovu narazili po~dopøedné hranì. V~ukázkovém grafu hrana: $(A \rightarrow D)$. +\s{Pozorování:} Chod algoritmu mù¾eme popsat posloupností závorek: $(_v$ bude +znaèit \uv{vstoupili jsme do~vrcholu~$v$} (a nastavili $\(v)$), $)_v$ budi¾ +opu¹tìní vrcholu (nastavení $\(v)$). Tato posloupnost bude správnì uzávorkovaná, +èili páry závorek se nebudou køí¾it. -Posledním typem hran je {\I pøíèná} hrana. Ta vede do~vrcholu v~sousedním podstromì zprava doleva. V~tomto pøípadì jsme tedy nejdøíve objevili vrchol $w$, ten jsme následnì opustili a a¾ pak jsme objevili vrchol $v$. V~ukázkovém grafu to je hrana: $(D \rightarrow C)$. - -\s{K zamy¹lení:} Proè nemohou vést pøíèné hrany také zleva doprava? - -K~rozpoznávání typù hran se nám tedy velmi hodí pole $\$ a $\$, ve~kterých si pamatujeme èasy objevení a opu¹tìní vrcholu. Podle toho, jak se intervaly objevení a opu¹tìní obou vrcholù pøekrývají, mù¾eme jednoznaènì rozhodnout, o jaký typ hrany se jedná: - -U~zpìtných hran je poøadí: $\(w)$, $\(v)$, $\(v)$, $\(w)$. Intervaly do~sebe budou zanoøené takto: $<<>_v>_w$. - -U~dopøedných hran je poøadí: $\(v)$, $\(w)$, $\(w)$, $\(v)$. Intervaly do~sebe budou zanoøené takto: $<<>_w>_v$. - -U~pøíèných hran je poøadí: $\(w)$, $\(w)$, $\(v)$, $\(v)$. Intervaly do~sebe budou zanoøené takto: $<>_w<>_v$. - -Pozn: Pou¾íváme zde toto znaèení: $<>_v = $. Jedná se o interval objevení a opu¹tìní vrcholu $v$. - -\s{Typy hran ($v \rightarrow w$):} +\s{Klasifikace hran:} DFS dìlí hrany na následující ètyøi druhy. Hrana $uv$ je: \itemize\ibull -\:Stromové hrany \dots po nich DFS pro¹lo. $\{(A \rightarrow B), (B \rightarrow C), (B \rightarrow D)\}$ -\:Zpìtné hrany $<<>_v>_w$\dots vedou do~pøedchùdce $v$ ve~stromu. $\{(C \rightarrow A)\}$ -\:Dopøedné hrany $<<>_w>_v$\dots vedou do~potomka. $v$ $\{(A \rightarrow D)\}$ -\:Pøíèné hrany $<>_w<>_v$\dots vedou do~vrcholu $v$ v~sousedním podstromì, v¾dy zprava doleva. $\{(D \rightarrow A)\}$ +\:{\I Stromová} (na na¹em obrázku plná) pokud po ní DFS pro¹lo do neoznaèeného vrcholu. V¹imnìte si, + ¾e stromové hrany spoleènì tvoøí strom orientovaný od koøene~$v_0$. (Je to + strom, jeliko¾ vzniká postupným pøidáváním listù.) Tomuto stromu se øíká DFS strom. +\:{\I Zpìtná} (teèkovaná) -- taková hrana vede do~vrcholu, do kterého jsme + vstoupili, ale je¹tì jsme ho neopustili (to je vrchol, který máme pøi rekurzi na zásobníku). + Odpovídá uzávorkování $(_v \dots (_u \dots )_u \dots )_v$. +\:{\I Dopøedná} (èárkovaná) -- vede do vrcholu, který jsme u¾ opustili, ale který je + potomkem aktuálního vrcholu: $(_u \dots (_v \dots )_v \dots )_u$. +\:{\I Pøíèná} (èerchovaná) -- vede do vrcholu, který jsme u¾ opustili, ale který ve~stromu + nele¾í pod aktuálním vrcholem. Musí tedy vést do vrcholù \uv{nalevo} od stromové cesty + z~$v_0$ do~$u$. Napravo toti¾ le¾í vrcholy, které v~okam¾iku opou¹tìní~$u$ je¹tì nebyly + prozkoumané, tak¾e hrana $uv$ by se stala stromovou. Pøíèné hrany poznáme podle + uzávorkování $(_v \dots )_v \dots (_u \dots )_u$. +\:Jiné druhy hran nemohou existovat, probrali jsme toti¾ v¹echny mo¾nosti, v~jakém + vztahu mohou být páry závorek $(_u )_u$ a $(_v )_v$. \endlist - -\s{Pozorování:} Hrany, po~kterých DFS pro¹lo, tvoøí DFS strom. - -\s{Pozorování:} Intervaly ($\(v)$, $\(v)$) $\forall v \in V(G) $ tvoøí dobré uzávorkování. (Intervaly synù disjunktnì vyplòují otce $\Rightarrow$ intervaly se nemohou køí¾it). - -Nakonec si je¹tì uvìdomme, jak bude vypadat prohledávání do~hloubky na~neorientovaném grafu. Algortimus bude úplnì stejný, jenom se nám zredukuje poèet typù hran na~dvì: {\I stromové} a~{\I zpìtné}. Ani {\I dopøedné} ani {\I pøíèné} nebudou existovat, nebo» se z~{\I pøíèných} stanou {\I stromové} a z~{\I dopøedných zpìtné}. +Kterého typu hrana je, mù¾eme tedy poznat podle znaèky $Z[v]$ a podle hodnot \ a \ +vrcholù $u$ a~$v$. + +\s{Neorientované grafy:} V~neorientovaných grafech (ka¾dou hranu vidíme jako dvì orientované +hrany) je situace daleko jednodu¹¹í. Buïto hranu objevíme jako stromovou (a v~opaèném smìru +ji vidíme jako zpìtnou), nebo ji objevíme jako zpìtnou (a~v~opaèném smìru se jeví dopøednou). +Pøíèné hrany nemohou existovat, proto¾e k~nim opaèná hrana by byla pøíèná vedoucí zleva +doprava, co¾ víme, ¾e nenastane. \bye