TGH04 - procházky po grafech Jan Březina Technical University of Liberec 24. března 2015
Theseus v labyrintu Theseus chce v labyrintu najít Mínotaura. K dispozici má Ariadninu nit a křídu. Jak má postupovat?
Theseus v labyrintu Theseus chce v labyrintu najít Mínotaura. K dispozici má Ariadninu nit a křídu. Jak má postupovat? Odvíjením a navíjením niti si pamatuje cestu od vchodu.
Theseus v labyrintu Theseus chce v labyrintu najít Mínotaura. K dispozici má Ariadninu nit a křídu. Jak má postupovat? Odvíjením a navíjením niti si pamatuje cestu od vchodu. Aby prošel všechny chodby bludiště, dělá křížky tam kde už byl.
Theseus v grafu Labyrint je obyčejný neorientovaný souvislý graf. Nit je zásobník vrcholů. Příchod do vrcholu - je tam nit. Odchod z vrcholu - křížek.
Procházení do hloubky - rekurzivní DFS - deep first search Průchod vrcholu: 1. označím vrchol za navštívený 2. pro všechny hrany vedoucí do nenevštíveného sousedního vrcholu projdu sousední vrchol 3. označím vrchol za uzavřený
Procházení do hloubky - zadání Vstup algoritmu: (orientovaný) graf G daný vrcholy V a seznamem sousedů Adj[v] každého vrcholu v. Výstup: d[v] - čas previzity, prvního navštívení vrcholu, zšedivění f[v] - čas postvizity, opuštění vrcholu, zčernání π[v] - předci ve lese průchodu G π
Procházení do hloubky - algoritmus 1 for u V do color[u] = W hite, π[u] = NULL 2 time = 1 3 for u V do 4 if color[u] == W hite then DFSVisit (u) 5 procedure DFSVisit (u) 6 color[u] = Gray, d[u] = time++ // previsit 7 for v Adj[u] do if color[v] == W hite then 8 π[v] = u 9 DFSVisit (v) 10 11 color[u] = Black, f[u] = time++ // postvisit Barvy jsou pouze didaktické, potřeba je pouze odlišení bílých vrcholu a ty lze poznat vhodnou inicializací π[v], nebo d[v].
Procházení do hloubky - analýza Konečnost a korektnost Každou hranu projdeme právě jednou (řádek 6). Proč? Každý vrchol provede právě jednou previzit a jednou postvizit. Zobrazení π dává les obsahující všechny vrcholy. Složitost: řádky 1 3 O(V ) DFS-Visit volaná pro každý vrchol jednou cyklus 6 8 právě jednou pro každou hranu dohromady: O(V + E)
Závorkovací věta Theorem Pro libovolné dva vrcholy u a v jsou jajich itervaly otevřenosti (d[u], f[u]) a (d[v], f[v]) bud disjunktní, nebo do sebe vnořené, t.j. pokud d[u] < d[v] pak platí bud nebo d[u] < d[v] < f[v] < f[u] d[u] < f[u] < d[v] < f[v] vnořené disjunktní. Nemůže tedy nastat situace d[u] < d[v] < f[u] < f[v].
Důkaz Předpokládáme d[u] < d[v] pokud d[v] < f[u]: vrchol u je šedý při otevření v a zůstane šedý do uzavření v, tj. f[v] < f[u] máme tedy vnořené intervaly jelikož d[v] < f[v]. pokud d[v] > f[u]: vrchol u je černý při otevření v a tedy f[v] > d[v], tedy disjunktní intervaly.
Příklad
Klasifikace hran Pro orientovaný graf je hrana (u, v): stromová když je součástí vzniklého lesa, přišli jsme po ní do bílého vrcholu v zpětná pokud v je předkem u v lese G π přišli jsme po ní do šedivého vrcholu v dopředná pokud v je potomkem u v G π, ale ne bezprostředním; není stromová přišli jsme po ní do černého vrcholu a platí d[u] < d[v]; vnořené závorky d[u] < d[v] < f[v] < f[u] křížová všechny ostatní hrany přišli jsme po ní do černého vrcholu a platí d[u] > d[v]; disjunktní závorky d[v] < f[v] < d[u] < f[u] Pro neorientovaný... první typ který najdeme, tj nejsou křížové a dopředné.
Příklad
CPM - critical path method Motivační problém: dosažení složitého cíle (postavit dům, oblekaní dvouleté dcerky, napsání bakalářské práce) rozdělení na mnoho dílčích činností (vrcholy) určení minimálního času pro jejich splnění (ohodnocení vrcholů w[v]) určení jejich závislostí (orientované hrany), hrana vede z činnosti u do činnosti v, pokud v závisí na u Úloha: Jsou dány činnosti jejich doby a závislosti. Urči minimální čas potřebný k provedení všech činností. Pro každou činnost uči, kdy nejdříve může skončit a kdy nejpozději musí skončit, aby zůstal zachován celkový minimální čas. Najdi činnosti, pro které je rozdíl těchto časů nulový. Tyto tvoří kritickou cestu.
Gantt chart červeně: kritická cesta modře: nekritické činnosti černě: intervaly mezi minimálním a mximální časem dokončení
Grafová formulace Orientovaný acyklický graf (DAG) je orientovaný graf neobsahující cykly. Obsahuje alespoň jeden (startovní) uzel bez vstupní hrany a alespoň jeden (cílový) uzel bez výstupní hrany. BÚNO jeden startovní a jeden cílový (spojení startovních/cílových uzlu do jednoho) Grafová úloha: Pro daný orientovaný acyklický graf G(V, E) s ohodnocenými vrcholy w(v) najdi nejmenší číslo T tak, aby délka každé cesty (součet jejích vrcholů) ze startovního do cílového uzlu byla menší než T. Najdi cestu jejíž délka je rovna T.
Topologické třídění - algoritmus Jednodušší varianta CPM: Pro orientovaný graf zjisti jestli je to DAG a setřid vrcholy tak, aby hrana vždy šla z vrcholu s nižším číslem do vrcholu s vyšším číslem. 1. DFS, urči f[u] pro všechny vrcholy 2. ukončené vrcholy přidávej na začátek seznamu (seznam vrcholů setříděný sestupně podle f[u]) implementace: nepotřebujeme π[] ani f[], d[] pouze kvůli barvení při postvizitě vrcholu u: order.push_front(u) nebo efektivněji: back_order.push_back(u)
Topologické třídění - důkaz správnosti Lemma Graf je DAG právě tehdy, pokud DFS nenajde žádnou zpětnou hranu. Theorem Pro každou hranu (u, v) platí f[u] > f[v], t.j. výsledný seznam bude dobře setříděný. Důkaz podle druhu hrany procházené hrany (u, v), u šedý: stromová a dopředná - (v bílý) v je potomkem u, t.j. f[u] > f[v] zpětná - nemůže nastat (lemma) křížová - disjunktní závorky d[v] < f[v] < d[u] < f[u]
CPM - algoritmus 1. Proved topologické setřídění bez ohledu na ohodnocení. 2. Nastav t start [:] = 0, minimální časy začátků činností. 3. Procházej výsledný seznam dopředu a pro každý vrchol u a jeho hranu (u, v) proved t start [v] = max(t start [v], t start [u] + w[u]), (maximum z délek cest které vedou do v). Pro cílový vrchol v end dostáváme t start (v end ) = T = t end (v end ).
CPM - algoritmus 1. Proved topologické setřídění bez ohledu na ohodnocení. 2. Nastav t start [:] = 0, minimální časy začátků činností. 3. Procházej výsledný seznam dopředu a pro každý vrchol u a jeho hranu (u, v) proved t start [v] = max(t start [v], t start [u] + w[u]), (maximum z délek cest které vedou do v). Pro cílový vrchol v end dostáváme t start (v end ) = T = t end (v end ). 4. Nastav t end [:] = T, maximální časy ukončení činností. 5. Procházej seznam pozpátku a počítej pro každý vrchol u a jeho hranu (u, v) t end [u] = min(t end [u], t end (v) w(u)), (kdy nejpozději musím skončit, abych neposunul následující činnosti) 6. Průběžně zaznamenej kritickou cestu tvořenou vrcholy, pro které t end (v) t start (v) = w(v).
Silně souvislé komponenty orientovaného grafu silně souvislá komponenta je maximální množina vrcholů, kde pro každou uspořádanou dvojici (u, v) existuje cesta kontrakce hrany Splynutí jejích vrcholů v grafu. Necht W V G a indukovaný podgraf G[W ] je souvislý, pak kontrakce množiny W, je graf G.W který vznikne kontrakcí všech hran v G[W ]. metagraf orientovaného grafu vznikne kontrakcí jeho SSK
Příklad
Hledání SSK Algoritmus (Kosarajův algortimus) pro hledání SSK pomocí DFS: 1. DFS(G) urči časy postvisit f[u] 2. sestav transponovaný graf G T (opačně orientovaný) 3. DFS(G T ) hlavní cyklus sestupně podle hodnot f[u] 4. každý strom opovídá jedné komponentě Alterantivní mírně rychlejší jednopruchodový, ale složitější : Tarjanův algoritmus
správnost algoritmu Značení: d(c) = min{d[u], u C}, f(c) = max{f[u], u C} Lemma (kĺıčové) Necht C a C jsou SSK a existuje hrana z C do C, pak f(c) > f(c ). (největší časy postvisit jejich uzlů v prvním DFS) Důkaz: Než opustím C nutně musím projít C. V druhém DFS začínám na komponentě s max. f(c), tj. na G T z ní nevede hrana po jejím průchodu jdu do hlavního cyklu
Eulerova cesta úloha: Pro neorientovaný graf zjistit, zda se dá nakreslit jedním uzavřeným tahem a najít takový tah. Lemma V neorientovaném grafu G existuje uzavřený sled obsahující každou hranu právě jednou právě tehdy, když stupně všech vrcholů jsou sudé: v V : deg(v) = 2n
algoritmus 1. Z vrcholu v procházej graf (jako do hloubky, ale bez návratů) dokud se nevrátíš do v, označuj použité hrany. 2. Najdi ve výsledném sledu vrchol v s neprojitou hranou. Pokud takový neexistuje skonči. 3. Proved bod 1) a vlož nový sled do výsledného sledu na místo vrcholu v. 4. Pokračuj na 2) Pokud se pro ukládání sledu použije spojový seznam, má algoritmus složitost O(V + E).
detaily
Procházení do šířky I Vstup: graf G daný vrcholy V a sousednostmi Adj[i], počáteční vrchol s Výstup: vzdálenosti d[i] od s, předci π[i] průchodového stromu 1 for u V do Color[u] = W hite 2 Color[s] = Gray; d[s] = 0; π[s] = NULL 3 ClearQueue ; EnQueue(s) 4 while u =DeQueue do 5 for v Adj[u] do 6 if Color[v] == W hite then 7 Color[v] = Gray; d[v] = d[u] + 1; π[v] = u 8 EnQueue(v) 9 Color[u] = Black
Procházení do šířky II Breadth First Search (BFS) pro orientované i neorientované grafy vygeneruje kořenový strom vrcholů dosažitelných z s (stejná komponenta) čas: V (vložení a vybrání z fronty)+každá hrana= Θ( V + E ) pamět : reprezentace grafu V + E d[v] je délka nejkratší cesty z s do v kostra souvislého grafu je jeho maximální indukovaný podstrom... zde strom daný předky π[v] Vnější inicializací a cyklem přes všechny bílé vrcholy detekování komponent
Příště třídění, pokročilé datové struktury časová a pamět ová složitost