Přidání poznámek z 10. přednášky z PPA2

This commit is contained in:
Filip Znachor 2023-04-28 09:52:51 +02:00
parent 9c11f49a91
commit 6b61f516ab
1 changed files with 202 additions and 0 deletions

202
KIV PPA2/Prednaska10.md Normal file
View File

@ -0,0 +1,202 @@
# Graf
- podchycuje obecný vztah (relaci) mezi prvky
- strom je speciální typ grafu
### Druhy grafů
- **Orientovaný graf**
- podchybuje nesymetrické vztahy
### Formální definice
- **Neorientovaný graf** $G$ je dvojice $V, E$:
- $V$ je množina vrcholů (vertex, vertices)
- $E$ je množina hran (edges)
- Hrana je dvouprvková množina $\{ a,b \}, a \in V, b \in V$ (nezáleží na pořadí)
- **Orientovaný graf** $G$ je dvojice $V, E$:
- $V$ je množina vrcholů (vertex, vertices)
- $E$ je množina hran (edges)
- Hrana je uspořádaná dvojice prvků $( a,b ), a \in V, b \in V$ (záleží na pořadí)
- mají šipku
**Značení**
- $\vert V\vert$ - počet vrcholů grafu
- $\vert E\vert$ - počet hran grafu
+ $V(G)$ - množina vrcholů grafu $G$
+ $V(E)$ - množina hran grafu $G$
- $y \in V$ je sousedem $x \in V$ právě když
- existuje orientovaná hrana $E = (x, y)$
- existuje neorientovaná hrana $E, x \in E, y \in E$
### Operace
- vytvoření grafu s danou množinou vrcholů $V$ (bez hran)
- přidání (ne)orientované hrany
- zjištění všech sousedů vrcholu $x \in V$
- zjištění, zda je $y \in V$ sousedem $x \in V$ (test sousednosti)
### Vrchol
- můžou s ním být asiciována data
- ADT Graf **neumožňuje** odebírat a přidávat vrcholy
- data vrcholů je možné **držet mimo ADT v poli**
- jedinou reprezentací vrcholu je jeho **index**
### Implementace
- seznamy sousednosti
- matice sousednosti
+ implementace se liší pro orientované a neorientované grafy
#### Implementace seznamem sousednosti
- každý vrchol má své sousedy uložené v ADT Seznam
- není vhodné použít např. `LinkedList`
- nevyužijeme většinu funkcionality
- program by byl neefektivní (konverze `int`/`Integer`)
- chceme vědět, jak věci fungují uvnitř
- použijeme vlastní implementaci se spojovacím prvkem
- typ dat: `int`
+ reference na první prvek každého seznamu jsou uloženy v poli velikosti $\vert V\vert$
**Operace**
- přidání hrany
- pro neorientovaný přidáme obě hrany (z **A** do **B** a zároveň z **B** do **A**)
- vkládáme na **začátek**, je to **rychlejší**
- nalezení sousedů
- projdeme náš seznam `edges`
- **složitost**
- záleží na počtu sousedů
- husté grafy: počet sousedů může být $\Omega(\vert V\vert)$
- řídké grafy: průměrný počet sousedů $\mathcal{O}(1)$
- test sousednosti
- projdeme všechny sousedy a porovnáváme s hledaným
- složitost jako u hledání sousedů
**Úprava na ohodnocený graf**
- na každé hraně má přiřazené číslo (např. délka cesty, propustnost, ...)
- do spojovacího prvku přidáme ohodnocení hrany
#### Implementace maticí sousednosti
**Orientovaný graf**
- Matice $\vert V\vert \times \vert V\vert$ obsahuje na pozici $[i, j]$
- **1**, pokud z $i$-tého vrcholu vede hrana do $j$-tého
- **0**, pokud ne
**Neorientovaný graf**
- Matice $\vert V\vert \times \vert V\vert$ obsahuje na pozici $[i, j]$ a $[j, i]$
- **1**, pokud z $i$-tého vrcholu vede hrana do $j$-tého
- **0**, pokud ne
**Reprezentace matice**
- `int[][]` - alokováno zbytečně moc paměti
- `byte[][]` - bude nám stačit
- `boolean[][]` - překladač i pro `boolean` alokuje celý `byte`
+ první index - **řádek**
+ druhý index - **sloupce**
**Operace**
- přidání hrany
- nastavíme 1 na [i, j] (u neorientovaného grafu na [i, j] i [j, i])
- nalezení sousedů vrcholu `v`
- projdeme celou řádku - `matrix[v][i]`
- složitost $\Theta(\vert V\vert)$ nezávisle na hustotě grafu
- test sousednosti
- zjištění, jestli na [i, j] je 1
- složitost $\mathcal{O}(1)$ nezávisle na hustotě grafu
**Úprava na ohodnocený graf**
- matice jako `double[][]`
- v matici na pozici [i, j] uložíme ohodnocení hrany
- na ostatních pozicích bude hodnota mimo rozsah ohodnocení
- `-1`, pokud ohodnocení nesmí být záporné
- `NaN`, pokud `NaN` není přípustným ohodnocením
- záleží na konkrétní aplikaci
#### Porovnání implementací
**Paměťová složitost**
- seznam: $\mathcal{O}(\vert V\vert + \vert E\vert)$
- matice: $\Omega(\vert V\vert^2)$
**Výpočetní složitost operací**
- vložení hrany
- seznam i matice: $\mathcal{O}(1)$
- nalezení sousedů vrcholu
- seznam: $\Omega(n)$, $n$ je počet sousedů vrcholu
- matice: $\Omega(\vert V\vert)$
- test sousednosti
- seznam: $\Omega(n)$, $n$ je počet sousedů vrcholu
- matice: $\mathcal{O}(1)$
**Záleží na hustotě grafu**
- Řídký graf
- $\vert E\vert \ll \vert V\vert^2$
- obvykle vhodnější implementace seznamem sousedů
- např. pro planární trojúhelníkové sítě se dá dokázat, že průměrný počet vrcholů je blízký 6
- složitost testu sousednosti v průměru $\mathcal{O}(1)$
- Hustý graf
- $\vert E\vert \simeq \vert V\vert^2$, případně $\vert E\vert = k\vert V\vert^2$ pro nějakou konstantu $k$
- obvykle vhodnější implementace maticí sousedů
### Procházení grafu
**Příklady**
- Existuje v grafu cesta z vrcholu A do B?
- **Graf**: bludiště
- **Vrchol**: křižovatka
- **Hrana**: cesta mazi křižovatkami
- **Úkol**: zjistit, zda existuje cesta z jednoho místa na jiné
+ Jak dlouhá (kolik hran) je nejkratší cesta z vrcholu A do vrcholu B?
+ **Graf**: vlaková spojení
+ **Vrchol**: nádraží
+ **Hrana**: mezi nádražími jede přímý spoj
+ **Úkol**: vyhledat spojení s nejmenším počtem přestupů
- Které vrcholy se v grafu vyskytují ve vzdálenosti menší než $k$ (počet hran)?
- **Graf**: síť kontaktů LinkedIn
- **Vrchol**: záznam osoby
- **Hrana**: konexe
- **Úkol**: prohledat konexe do úrovně $k$, zda obsahují hledanou osobu
+ Existuje v orientovaném grafu cyklus?
+ **Graf**: vztah buněk v tabulkovém kalkulátoru
+ **Vrchol**: buňka
+ **Hrana** $A \to B$: hodnota buňky $A$ zavísí na hodnotě buňky $B$
+ **Úkol**: zjistit, zda je možné tabulku vyhodnotit (nesmí obsahovat cyklus!)
- Přiřadit vrcholům indexy tak, že hrany vedou vždy od menšího indexu k většímu
- **Graf**: závislosti činností
- **Vrchol**: činnost
- **Hrana** $A \to B$: činnost $B$ může být vykonána, teprve když je činnost $A$ hotová
- **Úkol**: zjistit, v jakém pořadí je možné činnosti vykonat
#### Prohledávání do šířky (BFS)
- Breadth-First Search
+ zpracovává vrcholy grafu od vrcholu `s` v pořadí **od blízkých ke vzdáleným**
+ postup vyžaduje označování vrcholů
+ označení uložíme do pole délky $\vert V\vert$
+ možná označení vrcholů
+ nenavštívený (kód 0)
+ čekající na zpracování (kód 1)
+ hotový (kód 2)
+ vrcholy se vkládají do fronty
+ všechny vrcholy ve vzdálenosti `k` se zpracují před těmi se vzdáleností `> k`
**Pozorování**
- BFS je potřeba doplnit o nějaký užitečný kód
+ záleží to na řešeném problému
- BFS vždy zpracuje jen jednu komponentu (jen vrcholy dosažitelné ze startovního vrcholu)
- může se vyřešit pomocí metody `BFS_all`, která bude procházet `for`-cyklem všechny nezpracované vrcholy (kód 0)
**Složitost**
- vkládání do fronty
- každý vrchol jen jednou
- $\Omega(\vert V\vert)$
- procházení sousedů
- implementace grafu seznamem: $\mathcal{O}(\vert E\vert)$
- implementace grafu maticí: $\Omega(\vert V\vert^2)$
+ celkem
+ úplný, popř. hustý graf nebo implementace sousednosti maticí: $\Omega(\vert V\vert^2)$
+ implementace sousednosti seznamem: $\mathcal{O}(\vert V\vert + \vert E\vert)$
+ graf může mít počet hran až $\vert V\vert^2$