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...

  1. k ceně každé hrany přičteme
  2. 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\).

  1. 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\).

  1. Odfiltrujte hrany
  2. 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\).

  1. Odfiltrujte hrany
  2. Zkontrolujte souvislost
  3. 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:

  1. nalezněte min. kostru \(T\)
  2. 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.)

Na
Viděnou
Za týden :)