LAB 02
B4M33PAL - Ing. David Pařil
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
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 MSTPseudokó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 MSTCena 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í
4
8
7
9
10
14
4
2
1
8
11
7
2
6
A
B
H
I
C
G
D
E
F
8
10
14
4
8
11
7
6
A
B
H
I
C
G
D
E
F
Fialová?
Zelená?
Oranžová?
A
B
H
I
C
G
D
E
F
A
B
H
I
C
G
D
E
F
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)
A
B
H
I
C
G
D
E
F
4
8
7
9
10
14
4
2
1
8
11
7
2
6
A
B
H
I
C
G
D
E
F
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
A
B
H
I
C
G
D
E
F
4
8
7
9
10
14
4
2
1
8
11
7
2
6
A
B
H
I
C
G
D
E
F
4
8
7
9
10
14
4
2
1
8
11
7
2
6
A
B
H
I
C
G
D
E
F
8
7
9
10
14
4
2
1
8
11
7
2
6
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
7
9
10
14
4
2
7
2
6
A
B
H
I
C
G
D
E
F
8
7
9
10
14
4
7
2
6
A
B
H
I
C
G
D
E
F
7
9
10
14
7
2
6
A
B
H
I
C
G
D
E
F
7
9
10
14
A
B
H
I
C
G
D
E
F
9
10
14
A
B
H
I
C
G
D
E
F
V grafu...
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)
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\).
Ř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\).
Ř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\).
Uveďte asymptotickou složitost algoritmu hledání minimální kostry:
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é ✅
Vážený neorientovaný graf \(G\) je reprezentován váhovou maticí \(C\).
Určete asymptotickou složitost Kruskalova algoritmu za předpokladu, že:
Ř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)\)
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:
Což odpovídá matici sousednosti (\(n \approx \sqrt{X \cdot 10^9}\)) o velikosti:
\(\rightarrow\) CPU by zvládlo \(\approx 10^5 - 10^6\) uzlů (noc = 10 hodin)
V souvislém ohodnoceném grafu \(G\) s \(n\) uzly a \(m = 5n\) hranami:
Navrhněte algoritmus, který řeší tuto úlohu.
Určete jeho asymptotickou složitost.
Řešení
Najděte min. kostru \(T\)
Pro řidký graf m \(m=5n \Rightarrow O(m \log n) = O(n \log n)\)
Najdi a odstraň \(e_{min}\) v \(T\)
Procházíme \(n-1\) hran \(T\) \(\rightarrow\) \(O(n)\)
Urči řez \((A,B)\)
DFS/BFS z obou konců \(e_{min}\). Označíme jako A/B. Celkem: \(O(n)\)
Vyber nejdražší "přemosťují
\(\forall e = (u,v) \in E: iff u \in A, v \in B\) (nebo naopak), sledujte maximum; \(O(n)\)
Najděte min. kostru \(T\)
Pro řidký graf m \(m=5n \Rightarrow O(m \log n) = O(n \log n)\)
Najdi a odstraň \(e_{min}\) v \(T\)
Procházíme \(n-1\) hran \(T\) \(\rightarrow\) \(O(n)\)
Urči řez \((A,B)\)
DFS/BFS z obou konců \(e_{min}\). Označíme jako A/B. Celkem: \(O(n)\)
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)\)
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...
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
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.
4) Zlevnila se hrana mimo MST
Máme nový \(MST\) :)
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 :(
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.)