TGH05 - aplikace DFS, průchod do šířky Jan Březina Technical University of Liberec 31. března 2015
Grafová formulace CPM (critical path method) 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.
CPM - algoritmus 1. Předpokládáme, že cílový vrchol má ohodnocení 0. 2. Proved topologické setřídění bez ohledu na ohodnocení. 3. Nastav t start [:] = 0, minimální časy začátků činností. 4. 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 ) + w[v end ] = T = t end (v end ).
CPM - algoritmus 1. Předpokládáme, že cílový vrchol má ohodnocení 0. 2. Proved topologické setřídění bez ohledu na ohodnocení. 3. Nastav t start [:] = 0, minimální časy začátků činností. 4. 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 ) + w[v end ] = T = t end (v end ). 5. Nastav t end [:] = T, maximální časy ukončení činností. 6. 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(v)), (kdy nejpozději musím skončit, abych neposunul následující činnosti) 7. Průběžně zaznamenej kritickou cestu tvořenou vrcholy, pro které t end (v) t start (v) = w(v).
Topologické setřídění: E B C D A Příklad D=4 4 8 E=1 B=3 0 1 1 4 A=5 8 13 C=2 4 8 E B C D A 0 1 4 8 13
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
Důležitá pozorování Lemma (o metagrafu) Metagraf je DAG (orientovaný graf bez cyklů). Značení po provedení DFS: d(c) = min{d[u], u C}, čas příchodu do komponenty C f(c) = max{f[u], u C}, čas odchodu z komponenty C Lemma (o zdrojové komonentě) Necht C a C jsou SSK a existuje hrana z C do C, pak f(c) > f(c ). (Čas odchodu je vyšší u komponenty ze které vede hrana.) Důkaz: Bud nejprve navštívím nějaký vrchol v C nebo nějaký vrchol v C. V obou případech později opustím C.
Hledání SSK Algoritmus pro hledání SSK pomocí DFS: 1. Proved DFS(G), urči časy postvisit f[u]. 2. Sestav transponovaný graf G T (opačně orientovaný), 3. Proved DFS(G T ). Hlavní cyklus sestupně podle hodnot f[u]. Provádíme odtrhávání zdrojových komponent metagrafu. 4. Každý strom lesa průchodu odpovídá jedné komponentě
Hledání SSK Algoritmus pro hledání SSK pomocí DFS: 1. Proved DFS(G), urči časy postvisit f[u]. 2. Sestav transponovaný graf G T (opačně orientovaný), 3. Proved DFS(G T ). Hlavní cyklus sestupně podle hodnot f[u]. Provádíme odtrhávání zdrojových komponent metagrafu. 4. Každý strom lesa průchodu odpovídá jedné komponentě Správnost algoritmu: V druhém DFS začínám na komponentě s max. f(c), podle lematu je to zdrojový vrchol metagrafu komponent (zdrojová komponenta) a na G T z ní nevede hrana. Po jejím průchodu zůstává v platnosti invariant: Komponenta s max. f(c) je zdrojová komonenta zbylého metagrafu.
Eulerova cesta úloha: Pro souvislý neorientovaný graf zjistit, zda se dá nakreslit jedním uzavřeným tahem a najít takový tah. Lemma V souvislém 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 Stupně musí být sudé, protože do každého vrcholu přijdeme tolikrát kolikrát odejdeme. Sudost vrcholů zaručuje existenci Eulerovského sledu.. viz. následující algoritmus.
Algoritmus pro Eulerovský tah 1. Z vrcholu v procházej graf (jako do hloubky, ale bez návratů) dokud se nevrátíš do v, odstraňuj (označuj) použité hrany. Musím se vrátit do v jelikož po jeho opuštění je to jediný vrchol lichého stupně. 2. Najdi ve výsledném sledu vrchol v s neprojitou hranou. Pokud takový neexistuje skonči. 3. Pokud existuje proved rekurzivně bod 1) a vlož sled do výsledného sledu na místo vrcholu v. Při vhodné implementaci 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
Nejkratší cesta Lemma (o správnost BFS) Po průběhu BFS (na jedné komonentě) je hodnota d[u] rovna délce nejkratší cesty z s do u. Důkaz indukcí: (TODO - udělat pořádně) Pro d[s] = 0 tvrzení platí. Dokážeme, že pokud platí pro vrcholy, kde d[u] n, pak platí i pro ty kde je d[u] n + 1. Sporem necht u je vrchol, kde d[u] = n + 1 a existuje cesta délky ns poslední hranou {w, u} Při BFS jsem do u mohl přijít z vrcholu v, který byl do fronty dán před w. hodnota d vrcohlů ve frontě neklesá (rozmyslet), proto: d[u] = d[v] + 1, a d[v] d[w] Dále jsem mohl do u přijít přímo z w, pak v každém případě je d[u] = d[w] + 1 n + 1 d[u] nebo Pro w je tedy d[w] n 1 již správně (indukční předpoklad).