Reprezentace grafů, kostry, union-find
LAB 02
B4M33PAL - Ing. David Pařil
Přednáška time
Hledání minimální kostry

Mějme následující graf:
A
B
H
I
C
G
D
E
F
4
8
7
9
10
14
4
2
1
8
11
7
2
6
Připomeňme si 3 základní algoritmy na vytváření minimální kostry...
A
B
H
I
C
G
D
E
F
4
8
7
9
10
14
4
2
1
8
11
7
2
6
Borůvkův algoritmus
Hledání minimální kostry

Idea:
1) Pro každou komponentu zvol nejlevnější incidentní hranu
2) Komponenty se slučují
3) Opakuj, dokud není jedna komponenta
MST ← ∅
Každý vrchol je vlastní komponenta (DSU)
while počet komponent > 1:
for každou komponentu C:
najdi nejlevnější hranu (u,v) s u∈C, v∉C
ulož jí do MST
sjednoť komponenty (union)
return MST
Pseudokód:
Kolik je fází?
MST ← ∅
Každý vrchol je vlastní komponenta (DSU)
while počet komponent > 1:
for každou komponentu C:
najdi nejlevnější hranu (u,v) s u∈C, v∉C
ulož jí do MST
sjednoť komponenty (union)
return MST
Cena fáze:
Nalezení hrany: \(O(E)\) (nejlevnější hrany)
Sjednocení: \(O(E)\) (s využitím Union-Find)
Celková složitost: \(O(E \log V)\)
Otázka:
Jaká část algoritmu lze paralelizovat?
1. fáze: \(V\) komponent
2. fáze: \(\leq \frac V 2\) komponent
3. fáze \(\leq \frac V 4\) komponent
...
\(\Rightarrow\) nejvýše \([\log_2 V]\) fází
Fáze 1:
4
8
7
9
10
14
4
2
1
8
11
7
2
6
A
B
H
I
C
G
D
E
F
Fáze 2:
8
10
14
4
8
11
7
6
A
B
H
I
C
G
D
E
F
Fialová?
Zelená?
Oranžová?
Fáze 3:
A
B
H
I
C
G
D
E
F
A
B
H
I
C
G
D
E
F
Kruskalův algoritmus
Hledání minimální kostry
Idea:
1) Seřaď hrany podle váhy vzestupně
2) Procházej hrany a přidej je, pokud nespojí cyklus
A
B
H
I
C
G
D
E
F
4
8
7
9
10
14
4
2
1
8
11
7
2
6
MST ← ∅
seřaď hrany E podle váhy
inicializuj DSU s |V| množinami
for (u,v,w) v E podle pořadí:
if find(u) ≠ find(v):
MST ← MST ∪ {(u,v,w)}
union(u,v)
return MST
Pseudokód:
Asymptotická složitost?
Otázka:
Jaká část algoritmu lze paralelizovat?
Třídění hran: \(O(E \log E) \)
Union-Find: až \(O(E \alpha V)\)
Celková: \(O(E \log E)\)
MST ← ∅
seřaď hrany E podle váhy
inicializuj DSU s |V| množinami
for (u,v,w) v E podle pořadí:
if find(u) ≠ find(v):
MST ← MST ∪ {(u,v,w)}
union(u,v)
return MST
(inverzní Ackermannova funkce - téměř konstantní)
(Po optimalizaci DSU)
Vizualizace:
A
B
H
I
C
G
D
E
F
4
8
7
9
10
14
4
2
1
8
11
7
2
6
Vizualizace:
A
B
H
I
C
G
D
E
F
Primův–Jarníkův algoritmus
Hledání minimální kostry
Idea:
1) Začni budovat strom z náhodného \(v\)
2)Rozšiřuj strom o nejlevnější hranu překračující "do neznáma"
A
B
H
I
C
G
D
E
F
4
8
7
9
10
14
4
2
1
8
11
7
2
6
vyber libovolný start s
visited[s] ← true
pro každého souseda v s: push (w(s,v), s, v) do heapu
MST ← ∅
while heap není prázdný a |MST| < |V|-1:
(w,u,v) ← pop-min
if visited[v]: continue
MST ← MST ∪ {(u,v,w)}
visited[v] ← true
pro každého souseda x v: if !visited[x]: push (w(v,x), v, x)
return MST
Pseudokód:
Asymptotická složitost?
Otázka:
Jaká část algoritmu lze paralelizovat?
Projetí všech hran: \(O(E) \)
Vložení do heapu: \(O(\log V)\)
Celková: \(O(E \log V)\)
vyber libovolný start s
visited[s] ← true
pro každého souseda v s: push (w(s,v), s, v) do heapu
MST ← ∅
while heap není prázdný a |MST| < |V|-1:
(w,u,v) ← pop-min
if visited[v]: continue
MST ← MST ∪ {(u,v,w)}
visited[v] ← true
pro každého souseda x v: if !visited[x]: push (w(v,x), v, x)
return MST
Krok 0:
A
B
H
I
C
G
D
E
F
4
8
7
9
10
14
4
2
1
8
11
7
2
6
Krok 1:
A
B
H
I
C
G
D
E
F
4
8
7
9
10
14
4
2
1
8
11
7
2
6
Krok 2:
A
B
H
I
C
G
D
E
F
8
7
9
10
14
4
2
1
8
11
7
2
6
Krok 3:
A
B
H
I
C
G
D
E
F
8
7
9
10
14
4
2
1
7
2
6
Krok 4:
A
B
H
I
C
G
D
E
F
8
7
9
10
14
4
2
7
2
6
Krok 5:
A
B
H
I
C
G
D
E
F
8
7
9
10
14
4
7
2
6
Krok 6:
A
B
H
I
C
G
D
E
F
7
9
10
14
7
2
6
Krok 7:
A
B
H
I
C
G
D
E
F
7
9
10
14
Krok 8:
A
B
H
I
C
G
D
E
F
9
10
14
Výsledný graf:
A
B
H
I
C
G
D
E
F
Příklad
Cena -> minimální kostra
V grafu...
- k ceně každé hrany přičteme
- vynásobíme ceny všech hran
stejnou konstantou \(c \neq 0\).
V jakém vztahu budou minimální kostry původního a upraveného grafu?
(Předpokládejte, že původní minimální kostra je určena jednoznačně)
A) Přičítáme \(c\)
A
B
H
I
C
G
D
E
F
4
8
7
9
10
14
4
2
1
8
11
7
2
6
Každý spanning tree má \(n - 1\) hran
Cena libovolného spanning tree se navýší přesně o \((n-1)\cdot c\)
Všem kostrám se tedy přičte stejná konstanta \(\rightarrow\) minimální kostra zůstane stejná
B) Přičítáme \(c\)
Cena každé kostry se změní na \(c \cdot w(T)\)
A
B
H
I
C
G
D
E
F
4
8
7
9
10
14
4
2
1
8
11
7
2
6
Pokud \(c > 0\), je transformace ryze rostoucí, pořadí se nemění.
Pokud \(c < 0\), je transformace ryze klesající, pořadí se obrátí.
(Minimální kostra v upraveném grafu odpovídá maximální kostře v původním)
Příklad
Kostra v Intervalu
Máme najít kostru (nikoliv nutně minimální).
Cena každé hrany kostry musí ležet v intervalu \(\langle c_1, c_2\rangle\).
Je nutno použít algoritmus pro hledání minimální kostry nebo stačí nějaký jednodušší postup?
Řešení
Příklad: hrany v intervalu \(\langle 4, 10\rangle\).
A
B
H
I
C
G
D
E
F
4
8
7
9
10
14
4
2
1
8
11
7
2
6
Řešení
A
B
H
I
C
G
D
E
F
4
8
7
9
10
4
8
7
6
Příklad: hrany v intervalu \(\langle 4, 10\rangle\).
- Odfiltrujte hrany
Řešení
A
B
H
I
C
G
D
E
F
4
8
7
9
10
4
8
7
6
Příklad: hrany v intervalu \(\langle 4, 10\rangle\).
- Odfiltrujte hrany
- Zkontrolujte souvislost
Řešení
A
B
H
I
C
G
D
E
F
4
8
7
9
10
4
8
7
6
Příklad: hrany v intervalu \(\langle 4, 10\rangle\).
- Odfiltrujte hrany
- Zkontrolujte souvislost
- Vraťte kostru
Příklad
Asymptotická složitost Hledání minimální kostry
Uveďte asymptotickou složitost algoritmu hledání minimální kostry:
Prim
Kruskal
Který bude rychlejší pokud je počet hran grafu čtyřnásobkem počtu uzlů?
Řešení
Prim: \(O(E \log V)\) (s binární haldou + seznamy sousedů)
Kruskal: \(O(E \log E)\) = \(O(E \log V)\)
\(\Rightarrow\) asymptoticky jsou stejně rychlé ✅
Příklad
Asymptotická složitost "Speciálního" union-findu
Vážený neorientovaný graf \(G\) je reprezentován váhovou maticí \(C\).
Určete asymptotickou složitost Kruskalova algoritmu za předpokladu, že:
- doba přístupu ke každému prvku \(C\) je konstantní, ale...
- doba každé jednotlivé operace Union i Find je vždy úměrná počtu uzlů v grafu G
Řešení
Vyčtení hran z matice:
\(O(V^2)\)
Seřazení hran:
\(O(E \log E)\)
Union-Find přes hrany:
\(O(E V)\)
Na každé hraně uděláme Find/Union, každá operace stojí ~\(O(V)\)
Hran je \(|E| \leq (\frac n 2)\)
Pro hustý graf dominuje \(m n \Rightarrow O(n^3)\)
Příklad
Deadline v 6:00
Hledáme minimální kostru úplného váženého grafu.
Odhadněte, kolik řádově nejvýše uzlů může takový graf mít, abyste úlohu vyřešili přes noc do druhého dne.
Zdůvodněte svůj odhad.
Řešení
Problém je s pamětí:
Řekněme, že váhy držíme jako 64-bit int, pak:
- 16GB RAM \(\Rightarrow \frac {16\cdot 10^9} 8 = 2 \cdot 10^9\) hodnot
- 32GB RAM \(\Rightarrow \frac {32\cdot 10^9} 8 = 4 \cdot 10^9\) hodnot
Což odpovídá matici sousednosti (\(n \approx \sqrt{X \cdot 10^9}\)) o velikosti:
- 16GB RAM \(\Rightarrow n \approx 45 000\) vah
- 32GB RAM \(\Rightarrow n \approx 65 000\) vah
\(\rightarrow\) CPU by zvládlo \(\approx 10^5 - 10^6\) uzlů (noc = 10 hodin)
Příklad
Aktualizace kostry
V souvislém ohodnoceném grafu \(G\) s \(n\) uzly a \(m = 5n\) hranami:
- nalezněte min. kostru \(T\)
- vyrobte jiinou kostru \(T_1\) (ne nutně minimální) tak, že nejlacinější hranu \(T\) odstraníme a do vzniklého nesouvislého grafu přidáme nejdražší možnou hranu z \(G\) tak, aby byl výsledný graf opět stromem/kostrou.
Navrhněte algoritmus, který řeší tuto úlohu.
Určete jeho asymptotickou složitost.
Řešení
1
Najděte min. kostru \(T\)
Pro řidký graf m \(m=5n \Rightarrow O(m \log n) = O(n \log n)\)
2
Najdi a odstraň \(e_{min}\) v \(T\)
Procházíme \(n-1\) hran \(T\) \(\rightarrow\) \(O(n)\)
3
Urči řez \((A,B)\)
DFS/BFS z obou konců \(e_{min}\). Označíme jako A/B. Celkem: \(O(n)\)
4
Vyber nejdražší "přemosťují
\(\forall e = (u,v) \in E: iff u \in A, v \in B\) (nebo naopak), sledujte maximum; \(O(n)\)
1
Najděte min. kostru \(T\)
Pro řidký graf m \(m=5n \Rightarrow O(m \log n) = O(n \log n)\)
2
Najdi a odstraň \(e_{min}\) v \(T\)
Procházíme \(n-1\) hran \(T\) \(\rightarrow\) \(O(n)\)
3
Urči řez \((A,B)\)
DFS/BFS z obou konců \(e_{min}\). Označíme jako A/B. Celkem: \(O(n)\)
4
Vyber nejdražší "přemosťují
\(\forall e = (u,v) \in E: iff u \in A, v \in B\) (nebo naopak), sledujte maximum; \(O(n)\)
Složitost: \(O(n \log n)\)
Příklad
Velitelství Graphlandu
Velitelství Graphlandu hledá co nejlacinější kostru grafu s tím omezením, že u některých hran grafu je předepsáno, že v kostře musí být bez ohledu na jejich cenu.
\(\rightarrow\) Lze tedy čekat, že výsledná kostra nebude nejlacinější možná.
Nicméně i v tomto případě lze použít jeden z algoritmů hledání minimální kostry pro splnění úlohy. Naštěstí žádná podmnožina předepsaných hran netvoří kružnici. Napište algoritmus vašeho řešení a určete jeho asymptotickou složitost.
Řešení
Stačí váhám požadovaných hran nastavit extrémně nízký cost. Ale...
Prim
Kruskal
Který máme použít?
A
B
H
I
C
G
D
E
F
8
7
9
10
14
4
2
1
7
2
6
A
B
H
I
C
G
D
E
F
8
9
10
14
11
Příklad
Kostíci s.r.o.
Odevzdali jsme zákazníkovi minimální kostru jím dodaného grafu s \(N\gg10^6\)
Odpoledne zákazník volá, že v zadání je chyba:
Cena hrany mezi vrcholy \(2075154\) a \(11439446\) je ve skutečnosti o 17% jiná!
Veškerá data grafu i kostry jsou dosud na našem disku.
Máme určit v lineárním čase vzhledem k počtu vrcholů, zda tato změna ovlivní tvar a cenu minimální kostry, a pokud ano, vydat co možná nejkratší opravu, která se dá tlumočit zpět telefonem.
(levnější/dražší)
Mějme graf:
Změna hrany...
Co může nastat?
1) Zdražila se hrana mimo MST
Co se stane?
\(\Rightarrow\) Nic :)
2) Zdražila se hrana na MST
Co se stane?
\(\Rightarrow\) Potřebujeme lepší \(MST\)
2) Zdražila se hrana na MST
Odstraníme hranu z \(MST\)
Roztrhneme na 2 komponenty
Hledáme nejlevnější \(e\)
mezi \(\textcolor{Blue}{MST_1}\) a \(\textcolor{RoyalBlue}{MST_2}\)
3) Zlevnila se hrana na MST
Co se stane?
\(\Rightarrow\) Nic :)
4) Zlevnila se hrana mimo MST
Co se stane?
4) Zlevnila se hrana mimo MST
Přídáme hranu do MST
Vzniká právě 1 cyklus
4) Zlevnila se hrana mimo MST
Najdeme nejdražší hranu v cyklu
a odstraníme ji.
Nejdražší
4) Zlevnila se hrana mimo MST
Máme nový \(MST\) :)
Příklad
Rozbitá Borůvka
Vysvětlete, proč Borůvkův algoritmus hledání minimální kostry obsahuje podmínku vyžadující, aby váhy všech hran byly navzájem různé.
Uveďte příklad grafu, na němž by algoritmus selhal, kdyby algoritmus tuto podmínku neobsahoval.
Řešení:
1
1
1
Řešení:
1
1
1
Zacyklená
borůvka :(
Příklad
Nenasytný loupežník
Nenasytný loupežník odebírá z grafu co možná nejdražší hrany.
Nesmí ale graf rozpojit na dvě nebo více komponent, protože by byl odhalen a dopaden.
Když odebere maximum všeho, co se dá, zbyde z grafu jeho minimální kostra?

A
B
H
I
C
G
D
E
F
4
8
7
9
10
14
4
2
1
8
11
7
2
6
Řešení:
A
B
H
I
C
G
D
E
F
Řešení:
A
B
H
I
C
G
D
E
F
Kruskal
Reverzní Kruskal
(Reverse delete alg.)