DVOP PIT
Bc. Matěj Cajthaml — SSPŠ
©
spojenívrcholů, které jsou v $V$
$G_1 = (\{a, b, c\}, \{\{a, b\}, \{c, a\}\})$
graph LR a((a)) --- b((b)) a --- c((c))
Nápady na alternativní zápis?
Proč v definici nepoužíváme v množině hran uspořádanou dvojici?
Může být v grafu s $V = \{a, b, c\}$ hrana $\{a, a\}$? Proč?
Kolik hran může mít maximálně graf s $3$ vrcholy?
Kolik hran může mít maximálně graf s $4$ vrcholy?
Kolik hran může mít maximálně graf s $n$ vrcholy?
$K_n = (V, E)$, kde
$V = \{v_1, v_2, ..., v_n\}$ a
$E = \{\{v_i, v_j\} | v_i, v_j \in V\}$
$K_4$:
graph LR 1((1)) --- 2((2)) 1 --- 3((3)) 1 --- 4((4)) 2 --- 4 2 --- 3 3 --- 4
$P_n = (V, E)$, kde
$V = \{v_1, v_2, ..., v_n\}$ a
$E = \{\{v_i, v_{i+1}\} | v_i, v_{i+1} \in
V\}$
$P_4$:
graph LR 1((1)) --- 2((2)) 2 --- 3((3)) 3 --- 4((4))
$C_n = (V, E)$, kde
$V = \{v_1, v_2, ..., v_n\}$ a
$E = \{\{v_i, v_{i+1}\} | v_i, v_{i+1} \in
V\} \cup \{\{v_1, v_n\}\}$
$C_4$:
graph LR 1((1)) --- 2((2)) 2 --- 3((3)) 3 --- 4((4)) 4 --- 1
$S_n = (V, E)$, kde
$V = \{v_1, v_2, ..., v_n\}$ a
$E = \{\{v_1, v_i\} | v_i \in V \land i >
1\}$
$S_6$:
graph TD 1((1)) --- 4((4)) 1 --- 5((5)) 1 --- 2((2)) 1 --- 3((3)) 1 --- 6((6))
Nechť $G = (V, E)$ je graf. Pak:
$V(G)$ je množina vrcholů grafu $G$
$E(G)$ je množina hran grafu $G$
$|V(G)|$ je počet vrcholů grafu $G$
$|E(G)|$ je počet hran grafu $G$
Nechť $G = (V, E)$ je graf a $e = \{u, v\} \in E$. Pak:
$u$ je soused $v$
$v$ je soused $u$
Nechť $G = (V, E)$ je graf. Pak:
$\overline{G} = (V, \overline{E})$, kde
$\overline{E} = \{\{u, v\} | u, v \in V \land \{u, v\}
\notin E\}$
$\overline{G}$ je doplněk grafu $G$.
Tedy: $\overline{G}$ obsahuje všechny hrany, které $G$ neobsahuje
Jednotlivým grafům níže vytvořite doplněk grafu.
$G_1$:
graph LR 1((1)) --- 2((2)) 2 --- 3((3)) 4((4))
$G_2$:
graph LR 1((1)) --- 2((2)) 2 --- 3((3)) 3 --- 4((4)) 4 --- 1
$G_3$:
graph LR 1((1)) --- 2((2)) 2 --- 1 2 --- 3((3)) 3 --- 1 3 --- 2 4 --- 1 3 --- 4((4))
Nechť $G = (V, E)$ je graf a $v \in V$. Pak:
$N(v) = \{u \in V | \{u, v\} \in E\}$
$N(v)$ je okolí vrcholu $v$ a reprezentuje množinu všech vrcholů, které jsou s $v$ spojeny hranou.
Obsahuje okolí vrcholu $v$ — $N(v)$ i vrchol $v$?
Nechť $G = (V, E)$ je graf a $v \in V$. Pak:
$d(v) = |N(v)|$
$d(v)$ je stupeň vrcholu $v$ a reprezentuje počet hran, které jsou s $v$ spojeny.
Například:
1 | 2 | 3 | 4 | |
1 | 0 | 1 | 0 | 1 |
2 | 1 | 0 | 0 | 0 |
3 | 0 | 0 | 0 | 0 |
4 | 1 | 0 | 0 | 0 |
Nechť $G = (V_G, E_G)$ a $H = (V_H, E_H)$ je graf. Pak:
$H$ je podgraf grafu $G$ právě tehdy, když $V_H \subseteq V_G$ a $E_H \subseteq E_G$.
$G = (\{1, 2, 3, 4\}, \{\{1, 2\},\{2, 3\}, \{3, 4\}, \{4, 1\}\})$
$H = (\{1, 2, 3\}, \{\{1, 2\}, \{2, 3\}\})$
graph LR 1((1)) -.- 2((2)) 2 -.- 3((3)) 3 --- 4((4)) 4 --- 1 style 1 fill:#cd8f41,stroke:#333,stroke-width:4px style 2 fill:#cd8f41,stroke:#333,stroke-width:4px style 3 fill:#cd8f41,stroke:#333,stroke-width:4px
$H$ je podgraf $G$.
Mějme $G = (\{1, 2, 3\}, \{\{1, 2\}, \{3, 1\}\})$ a $H = (\{1, 2\}, \{\}\})$.
Je $H$ podgrafem
$G$?
Nechť $G = (V, E)$ je graf a $v_1, v_2, \dots, v_n \in V$. Pak:
$\{v_a, v_b, \dots, v_m\}$ je cesta v grafu $G$ právě tehdy, když $\{v_a, v_b\}, \{v_b, v_c\}, \dots, \{v_{m-1}, v_m\} \in E$.
Nechť $G = (V, E)$ je graf a $v_1, v_2, \dots, v_n \in V$. Pak:
Délka cesty $\{v_a, v_b, \dots, v_m\}$ je $m - 1$.
Tedy: počet hran v cestě.
Nechť $G = (V, E)$ je graf a $v_1, v_2, \dots, v_n \in V$. Pak:
$\{v_a, v_b, \dots, v_m\}$ je cyklus v grafu $G$
právě tehdy, když
$\{v_a, v_b\}, \dots,
\{v_{m-1}, v_m\}, \{v_m, v_a\} \in E$.
Máme-li cyklus v grafu $G$, je daný cyklus zároveň cestou v grafu $G$?
Nechť $G = (V, E)$ je graf. Pak:
$G$ je souvislý graf právě tehdy, když pro každé dva vrcholy $v, w \in V$ existuje cesta z $v$ do $w$.
Jinak je $G$ nesouvislý graf.
Pro každý graf $G$ zjistěte, zda je souvislý.
$G_1$:
graph LR 1((1)) --- 2((2)) 2 --- 3((3)) 3 --- 4((4)) 4 --- 1
$G_2$:
graph LR 1((1)) --- 2((2)) 2 --- 3((3)) 3 --- 4((4)) 4 --- 1 5((5)) --- 6((6)) 6 --- 7((7)) 7 --- 8((8)) 8 --- 5
$G_3$:
graph LR 1((1)) --- 2((2)) 2 --- 3((3)) 3 --- 4((4)) 4 --- 1 5((5)) 6((6)) 7((7)) 7 --- 8((8)) 8 --- 5 1 --- 5 3 --- 7 4 --- 8
Nechť $G = (V, E)$ je graf. Podgraf $H$ grafu $G$ je souvislá komponenta grafu $G$ právě tehdy:
graph LR 1((1)) --- 2((2)) 2 --- 3((3)) 3 --- 4((4)) 4 --- 1 2 --- 4 5((5)) --- 6((6)) 6 --- 7((7)) 7 --- 8((8)) 8 --- 6
Komponenty: $\{1, 2, 3, 4\}$, $\{5, 6, 7, 8\}$
Spousta algoritmů — my si ukážeme průchod do hloubky.
DFS(G, v):
if v is visited
return
mark v as visited
for every edge {v, w} in G
DFS(G, w)
Všechny označené vrcholy tvoří jednu komponentu a můžeme navštívit ze startovního vrcholu.
Proč je tento algoritmus správný?
Jaká je časová a prostorová asymptotická složitost?
Graf $G = (V, E)$ je strom právě tehdy, když:
Vrchol $v$ ve stromě $G$ je list právě tehdy, když $d(v) = 1$.
Tedy: má stupeň 1 = je spojen pouze s jedním vrcholem.
Strom s alespoň dvěma vrcholy má alespoň dva listy.
Jakto?
Operace odebrání listu $v$ ze stromu $G$:
Jakto?
Operace přidání listu $v$ do stromu $G$:
Graf $G = (V, E)$ je graf. Poté jsou následující tvrzení ekvivalentní:
Orientovaný graf je dvojice $G = (V, E)$, kde:
Hrany kreslíme šipkami.
graph LR A((A)) B((B)) C((C)) D((D)) A --> B B --> C C --> A C --> D
Pro orientované grafy definujeme:
Tyto pojmy zkuste definovat sami.
Nechť $G = (V, E)$ je orientovaný graf. Poté vstupní okolí vrcholu $v \in V$ je:
Nechť $G = (V, E)$ je orientovaný graf. Poté výstupní okolí vrcholu $v \in V$ je:
Nechť $G = (V, E)$ je orientovaný graf. Poté stupeň vrcholu $v \in V$ je:
Nechť $G = (V, E)$ je orientovaný graf. Poté vstupní stupeň vrcholu $v \in V$ je:
Nechť $G = (V, E)$ je orientovaný graf. Poté výstupní stupeň vrcholu $v \in V$ je:
Nechť $G = (V, E)$ je orientovaný graf. Poté stupeň vrcholu $v \in V$ je:
Nechť $G = (V, E)$ je orientovaný graf. Poté:
$v_1$ je zdroj, $v_5$ je stoka, $v_6$ je izolovaný vrchol
graph LR v1((v1)) v2((v2)) v3((v3)) v4((v4)) v5((v5)) v6((v6)) v1 --> v2 v1 --> v3 v2 --> v4 v3 --> v4 v4 --> v5
Graf $G$ je slabě souvislý, právě tehdy, když:
Z níže neorientovaného grafu vytvořte orientovaný graf dle předchozího schématu:
$G_1$:
graph LR v1((v1)) v2((v2)) v3((v3)) v1 --> v2 v2 --> v3 v3 --> v1
$G_2$:
graph LR v1((v1)) v2((v2)) v3((v3)) v4((v4)) v1 --> v2 v3 --> v4 v2 --> v3
$G_3$:
graph LR v1((v1)) v2((v2)) v3((v3)) v4((v4)) v5((v5)) v6((v6)) v3 --> v4 v3 --> v5 v4 --> v5 v1 --> v3 v1 --> v2 v6 --> v4
Graf $G$ je silně souvislý, právě tehdy, když:
graph LR 0((0)) 1((1)) 2((2)) 3((3)) 4((4)) 5((5)) 0 --> 1 1 --> 2 2 --> 5 2 --> 3 5 --> 2 3 --> 0 3 --> 4 4 --> 0
Jak můžeme algorithmicky zjistit, zda je graf silně souvislý?
Graf $K$ je kostra ke grafu $G$, právě tehdy, když:
Kolik koster může mít graf?
spanning_tree(G):
for every v in V(G):
mark v as unvisited
v := random_vertex(G)
DFS_spanning_tree(G, v)
DFS_spanning_tree(G, v):
mark v as visited
for every edge {v, w} in E(G):
if w is unvisited:
add {v, w} to spanning tree
DFS_spanning_tree(G, w)
Proč to funguje?
Jaká je časová a paměťová složitost?
BFS(G, v):
for every v in V(G):
mark v as unvisited
D[v] := undefined
P[v] := undefined
Q := empty_queue()
enqueue(v)
mark v as visited
D[v] := 0
while Q is not empty:
w := dequeue(Q)
for every edge {w, u} in E(G):
if u is unvisited:
enqueue(u)
mark u as visited
D[u] := D[w] + 1
P[u] := w
Proč to funguje?
Jaká je časová a paměťová složitost?
Strom je zakořeněný, pokud má jeden jeho vrchol označený jako kořen.
Vrcholy jsou uspořádány do úrovní, kde kořen je na úrovni 0 a každý vrchol na úrovni $i$ má potomky na úrovni $i+1$.
graph TD A((1)) --- B((2)) A --- C((3)) B --- D((4)) B --- E((5)) C --- F((6)) C --- G((7)) C --- H((8)) C --- I((9)) D --- J((10)) D --- K((11)) D --- L((12)) style A fill:#cd8f41
Strom je binární, pokud:
graph TD A(( )) --- B(( )) A --- C(( )) B --- D(( )) B --- E(( )) C --- G(( )) C --- F(( )) style A fill:#cd8f41 style G fill:#00000000,stroke:#00000000 linkStyle 4 stroke:#00000000,fill:#00000000
graph TD A((3)) --- B((5)) A --- C((7)) B --- D((8)) B --- E((9)) C --- F((11)) C --- G(( )) style A fill:#cd8f41 style G fill:#00000000,stroke:#00000000 linkStyle 5 stroke:#00000000,fill:#00000000
Kolik úrovní má binární minimová halda s $n$ vrcholy?
Kolik listů má binární minimová halda s $n$ vrcholy?
HeapInsert(H, x):
H.size = H.size + 1
insert x to the last level of H
BubbleUp(H, x)
BubbleUp(H, x):
if x is root of H:
return
y = parent of x
if x.key < y.key:
swap x and y
BubbleUp(H, y)
HeapDeleteMin(H):
x = root of H
y = last element of H
H.size = H.size - 1
swap x and y
BubbleDown(H, x)
BubbleDown(H, x):
if x is leaf:
return
y = child of x with the smallest key
if x.key > y.key:
swap x and y
BubbleDown(H, y)
Sepište pseudokód pro změnu hodnoty prvku v haldě tak, aby byla splněna podmínka minimové haldy.
Strom $T$ je binární vyhledávací strom (BVS/BST), pokud:
$T_1$:
graph TD 7((7)) 4((4)) 2((2)) 5((5)) 9((9)) 8((8)) 7 --- 4 7 --- 9 4 --- 2 4 --- 5 9 --- 8 9 --- E(( )) style E fill:#00000000,stroke:#00000000 linkStyle 5 stroke:#00000000,fill:#00000000
$T_2$:
graph TD 4((4)) 2((2)) 5((5)) E1(( )) E11(( )) 7((7)) E2(( )) E21(( )) 8((8)) E3(( )) E31(( )) 9((9)) 4 --- 2 4 --- 5 5 --- E1 E1 --- E11 5 --- 7 7 --- E2 E2 --- E21 7 --- 8 8 --- E3 E3 --- E31 8 --- 9 style E1 fill:#00000000,stroke:#00000000 style E2 fill:#00000000,stroke:#00000000 style E3 fill:#00000000,stroke:#00000000 style E11 fill:#00000000,stroke:#00000000 style E21 fill:#00000000,stroke:#00000000 style E31 fill:#00000000,stroke:#00000000 linkStyle 2 stroke:#00000000,fill:#00000000 linkStyle 3 stroke:#00000000,fill:#00000000 linkStyle 5 stroke:#00000000,fill:#00000000 linkStyle 6 stroke:#00000000,fill:#00000000 linkStyle 8 stroke:#00000000,fill:#00000000 linkStyle 9 stroke:#00000000,fill:#00000000
bst_show(T):
if T is not empty:
bst_show(T.left)
print(T.value)
bst_show(T.right)
bst_min(T):
if T is empty:
return null
if T.left is empty:
return T.value
return bst_min(T.left)
bst_prev(T, x):
if T is empty:
return null
if T.value == x:
if T.left is not empty:
return bst_max(T.left)
return null
if T.value > x:
return bst_prev(T.left, x)
r = bst_prev(T.right, x)
if r is null:
return T.value
return r
bst_find(T, x):
if T is empty:
return false
if T.value == x:
return true
if T.value > x:
return bst_find(T.left, x)
return bst_find(T.right, x)
bst_insert(T, x):
if T is empty:
return bst_create(x)
if T.value == x:
return T
if T.value > x:
T.left = bst_insert(T.left, x)
else:
T.right = bst_insert(T.right, x)
return T
bst_create(x):
T = new Node
T.value = x
T.left = null
T.right = null
return T
bst_remove(T, x):
if T is empty:
return null
if T.value == x:
if T.left is empty:
return T.right
if T.right is empty:
return T.left
T.value = bst_min(T.right)
T.right = bst_remove(T.right, T.value)
return T
if T.value > x:
T.left = bst_remove(T.left, x)
else:
T.right = bst_remove(T.right, x)
Kolik hladin může mít binární strom?
Binární vyhlazovací strom $T$ je dokonale vyvážený, pokud pro každý uzel $u$ platí, že
$|h(u.left)
- h(u.right)| \leq 1$.
$h(u)$ je počet hladin uzlu $u$.
Jednotlivým operacím BVS určete jejich časovou složitost.
Grafu $G = (V, E)$ říkáme ohodnocený, pokud:
Pro graf $G = (V, E)$ definujeme sled jako posloupnost vrcholů $(v_0, e_1, v_1, e_2, v_2, \dots, e_k, v_k)$, pro kterou platí:
Délka sledu $l(S)$ je součet délek jeho hran.
Jak se liší sled od cesty?
Pro libovolné dva vrcholy $u, v \in V$ definujeme vzdálenost $d(u, v)$ jako:
Pokud jsou délky hran kladné, pak pro každý $uv$-sled existuje $uv$-cesta stejné nebo menší délky.
Problém je NP-těžký, což znamená, že neočekáváme algoritmus, který by jej řešil v polynomiálním čase.
Pro speciální ohodnocení grafu můžeme problém řešit lépe.
Očekává pouze kladné ohodnocení hran.
Řeší obecný problém:
Pro zadaný orientovaný graf $G$ s kladnými délkami hran a zadaný počáteční vrchol $v_0$ nalezni vzdálenosti všech vrcholů grafu G od vrcholu $v_0$.
Pro jednotkové délky se algoritmus chová jako BFS.
Každou hranu o kladné délce větší jak 1 nahradíme cestou z jednotkových hran.
graph LR A((A))-- 4 -->B((B))
graph LR A((A))-- 1 -->A1(( )) A1-- 1 -->A2(( )) A2-- 1 -->A3(( )) A3-- 1 -->B((B))
Na novém grafu spustíme BFS. Tímto krokem budeme mít $O(L \cdot n)$ vrcholů a hran, kde $L$ je největší délka cest.
Dijkstra(G, v0):
for every v in V(G):
h(v) := infinity
P[v] := undefined
state[v] := notFound
h(v0) := 0
state[v0] := open
while there is an open vertex:
v := open vertex with the smallest h(v)
for every edge {v, w} in E(G): // záleží na typu grafu
if h(w) > h(v) + w(v, w):
h(w) := h(v) + w(v, w)
P[w] := v
state[w] := open
state[v] := closed
return P
To be continued...