From 175d2a37e1a885362b1907e627973bde97860282 Mon Sep 17 00:00:00 2001 From: Valentin Brandl Date: Tue, 13 Nov 2018 20:51:02 +0100 Subject: [PATCH] Add notes for dima on 20181113 --- school/di-ma/20181113_1-dag.md | 43 ++++++ school/di-ma/20181113_1-problem.dot | 7 + school/di-ma/20181113_1-topsort.dot | 14 ++ school/di-ma/20181113_2-adjlist.dot | 21 +++ school/di-ma/20181113_2-breitensuche.dot | 22 +++ school/di-ma/20181113_2-breitensuche.md | 168 +++++++++++++++++++++++ school/di-ma/index.md | 2 + 7 files changed, 277 insertions(+) create mode 100644 school/di-ma/20181113_1-dag.md create mode 100644 school/di-ma/20181113_1-problem.dot create mode 100644 school/di-ma/20181113_1-topsort.dot create mode 100644 school/di-ma/20181113_2-adjlist.dot create mode 100644 school/di-ma/20181113_2-breitensuche.dot create mode 100644 school/di-ma/20181113_2-breitensuche.md diff --git a/school/di-ma/20181113_1-dag.md b/school/di-ma/20181113_1-dag.md new file mode 100644 index 0000000..dcfacee --- /dev/null +++ b/school/di-ma/20181113_1-dag.md @@ -0,0 +1,43 @@ +--- +title: Directed Acyclic Graph +date: 2018-11-13 +--- + +Anwendung von gerichteten Graphen + + * Knoten sund Aufgaben (z.b. Berechnungen) + * Kanten $(u,v)$ falls Aufgabe $u$ vor Aufgabe $v$ erledigt werden muss + +**Beispiel**: + +![Beispielgraph](20181113_1-problem.png) + +Problem: Graph enthält einen Kreis => kann aufgaben nicht richtig anordnen und abarbeiten. + +## Definition (DAG; Directed Acyclic Graph) + +Ein gerichteter Graph $G = (V,E)$ heißt azyklisch (DAG) falls G keinen (gerichteten) Kreis enthält. + +## Definition (Topologische Sortierung) + +Sei $G = (V,E)$ ein gerichteter Graph. Eine Abbildung $f: V \to \{1, ... |V|\}$ mit der Eigenschaft, dass $f$ falls +$(u,v) \in E \Rightarrow f(u) < f(v)$ heißt **topologische Sortierung**. + +## Bemerkungen + +i) Topologische Sortierung entspricht für obige Anwendung einer (möglichen) Abarbeitungsreihenfolge +ii) Topologische Sortierung ist nicht eindeutig +iii) Später: Algorithmus um eine topologische Sortierung zu berechnen + +**Beispiel**: + +![Topologische Sortierung](20181113_1-topsort.png) + +$$ +f: \{A,B,C,D,E\} \to \{1,...,5\} \\ +f(A) = 2 \\ +f(B) = 1 \\ +f(C) = 3 \\ +f(D) = 4 \\ +f(E) = 5 +$$ diff --git a/school/di-ma/20181113_1-problem.dot b/school/di-ma/20181113_1-problem.dot new file mode 100644 index 0000000..1c0086d --- /dev/null +++ b/school/di-ma/20181113_1-problem.dot @@ -0,0 +1,7 @@ +digraph { + a [ label="", xlabel="Wohnung mieten" ]; + b [ label="", xlabel="Konto eröffnen" ]; + + a -> b; + b -> a; +} diff --git a/school/di-ma/20181113_1-topsort.dot b/school/di-ma/20181113_1-topsort.dot new file mode 100644 index 0000000..7b55f3c --- /dev/null +++ b/school/di-ma/20181113_1-topsort.dot @@ -0,0 +1,14 @@ +digraph { + a [ label="A", xlabel="2" ]; + b [ label="B", xlabel="1" ]; + c [ label="C", xlabel="3" ]; + d [ label="D", xlabel="4" ]; + e [ label="E", xlabel="5" ]; + + a -> d; + a -> c; + b -> a; + b -> c; + c -> e; + d -> e; +} diff --git a/school/di-ma/20181113_2-adjlist.dot b/school/di-ma/20181113_2-adjlist.dot new file mode 100644 index 0000000..924909d --- /dev/null +++ b/school/di-ma/20181113_2-adjlist.dot @@ -0,0 +1,21 @@ +graph { + { + rank=same; + 1; 3; + } + + { + rank=same; + 2; 4; + } + + { + rank=same; + 5; 6; + } + 1 -- 2 + 1 -- 3 + 1 -- 4 + 2 -- 4 + 5 -- 6 +} diff --git a/school/di-ma/20181113_2-breitensuche.dot b/school/di-ma/20181113_2-breitensuche.dot new file mode 100644 index 0000000..d6a9a11 --- /dev/null +++ b/school/di-ma/20181113_2-breitensuche.dot @@ -0,0 +1,22 @@ +graph { + rankdir=LR + { + rank=same; + 1 [ xlabel="0" ]; 3 [ xlabel="1" ]; + } + { + rank=same; + 2 [ xlabel="1" ]; 4 [ xlabel="1" ]; + } + { + rank=same; + 5 [ xlabel="2" ]; + } + + 1 -- 2; + 1 -- 3; + 1 -- 4; + 2 -- 5; + 4 -- 5; + +} diff --git a/school/di-ma/20181113_2-breitensuche.md b/school/di-ma/20181113_2-breitensuche.md new file mode 100644 index 0000000..2dc60b3 --- /dev/null +++ b/school/di-ma/20181113_2-breitensuche.md @@ -0,0 +1,168 @@ +--- +title: Breitensuche +date: 2018-11-13 +--- + +(ungerichtete Graphen) + +*Frage*: Gegeben ein Graph $G = (V,E)$ und $s \in V$. Wie finden wir die kürzesten Pfade zum Knoten +$u \in V \setminus \{s\}$? Ohne Einschränkung $V = \{1,...,n\}$. + +*Zuerst*: + +a) Speichern von Graphen + + Man möchte unter Anderem folgendes berechnen/testen: + + i) für $u,v \in V$ ist $\{u,v\} \in E$? + ii) $\Gamma(u) = \{v \in V \mid \{u,v\} \in E\}$ + + Der Aufwand für diese Operationen ist abhängig davon, wie wir den Graphen speichern. + + 1. Möglichkeit: + + Adjazenzmatrix $A$ mit $A_{ij} = \begin{cases} + 1 & \{i,j\} \in E \\ + 0 & \text{sonst} + \end{cases}$ + + Speicheraufwand: $O(n^2)$ + + * testen ob $\{u,v\} \in E$ kostet $O(1)$ (teste ob $A_{ij} = 1$ oder nicht) + * berechnen von $\Gamma(u)$ kostet $O(n)$ + + 1. Möglichkeit: + + Verkettete Listen (Adjazenzlisten) + + Für jeden Knoten $u \in \{1,...,n\}$ speichern wir eine (aufsteigend sortierte) Liste der Nachbarn von $u$. + + *Beispiel*: + + ![Graph](20181113_2-adjlist.png) + + | Knoten | Nachbarn | + | --- | --- | + | 1 | 2, 3, 4 | + | 2 | 1, 4 | + | 3 | 1 | + | 4 | 1, 2 | + | 5 | 6 | + | 6 | 5 | + + Speicherplatz: $\sum\limits_{u \in V} | \Gamma(u) | = \sum\limits_{u \in V} deg(u) = 2 |E| \Rightarrow O(n+|E|) + = O(|V| + |E|)$ + + * testen ob $\{u,v\} \in E$ kostet $O(min\{deg(u), deg(v)\})$ + * berechnen von $\Gamma(u)$. Nachbarschaft entspricht genau der Adjazenzliste. $O(|\Gamma(u)|) = O(deg(u))$ + +b) Warteschlange + + *Beispiel*: + + i) Supermarkt + ii) Kommunikationskanal + + **Abstraktion**: Sei $U$ eine endliche Menge. Eine Queue ist eine Datenstruktur mit folgenden Operationen: + + i) Erzeugen einer leeren Warteschlange `Q <- new Queue()` + ii) Einfügen von Elementen in die Warteschlange `Q.enqueue(u)` mit $u \in U$ + iii) Entfernen des *zuerst* hinzugefügten Elements aus der Warteschlange `u <- Q.dequeue()` + iv) Testen, ob die Warteschlange leer ist `Q.isEmpty()` + + Queue ist eine `FIFO` Datenstruktur + +Damit können wir die Breitensuche beschreiben. + +# Algorithmus (Breitensuche) + +*Eingabe*: Graph $G = (V,E)$ mit $V = \{1,...,n\}$ als Adjazenzliste und sei $s \in V$ + +i) für alle $v \in V\setminus\{s\}$ setze `d[v] =` $\infty$ und `pred[v] = NIL` +i) `d[s] = 0` +i) `Q <- new Queue()` +i) `Q.enqueue(s)` +i) `while (!Q.isEmpty())` + a) `v <- Q.dequeue()` + a) Für alle $u \in \Gamma(v)$ + Falls `d[u] =` $\infty$ dann + * setze `d[u] = d[v] + 1` + * setze `pred[u] = v` + * `Q.enqueue(u)` +i) *Ausgabe*: `d[u]`, `pred[u]` für alle $u \in V$ + +**Beispiel**: + +Startknoten: $s = 1$ + +![Breitensuche](20181113_2-breitensuche.png) + +| *Queue* | +| --- | +| **1** | +| **2**, 4, 3 | +| **4**, 3, 5 | +| **3**, 5 | +| **5** | + +| v | 1 | 2 | 3 | 4 | 5 | +| --- | --- | --- | --- | --- | --- | +| `d[v]` | 0 | 1 | 1 | 1 | 2 | +| `pred[v]` | | 1 | 1 | 1 | 2 | + +# Satz (Breitensuche) + +Sie Breitensuche liefert für den Startknoten $s$ die kürzesten $u$-$s$-Pfade für alle $u \in V$ als `p = (u, pred[u], +pred[pred[u]], ..., s)` in Laufzeit $O(|V| + |E|)$ + +# Beweis (Breitensuche) + +i) Laufzeit ist klar +i) **Korrektheit** + Für $u \in V$ ist `p = (u, pred[u], pred[pred[u]], ..., s)` ein Pfad in $G$ (da jeder Knoten maximal einmal in die + Queue eingefügt wird, gibt es keine Knotenwiederholung). Die Länge von `p` ist `d[u]`, da + * `d[u] - 1 = d[pred[u]]` + * `d[pred[pred[u]]] = d[pred[u]] - 1 = d[u] - 2` + + usw. bis `d[s] = 0`. + + Sei $p' = (v_0 = u, v_1, ... v_k = s)$ ein weiterer $u$-$s$-Pfad. Zu zeigen: `d[u]` $\leq$ `k`. Es gilt für alle + $\{u',v'\} \in E$ + + ``` + d[v'] <= d[u'] + 1 + ``` + + $\Rightarrow d[u] \leq d[v_1] + 1 \leq d[v_2] + 2 \leq ... \leq d[v_k] + k \leq d[s] + k = k$ + + $$ + \tag*{$\Box$} + $$ + +# Satz (Breitensuche $\to$ Spannbaum) + +Breitensuche liefert bei Eingabe eines zusammenhängenden Graph $G = (V,E)$ und $s \in V$ einen Spannbaum $T=(V,E')$ mit +$E' = \{\{u, pred[u]\} \mid u \in V \setminus \{s\}\}$ von $G$. + +# Beweis (Breitensuche $\to$ Spannbaum) + +Zu zeigen: $T$ ist Spannbaum von $G$, das heißt + +i) $T$ ist zusammenhängend + + Für $u,v \in V$ sind + + * $p = (u, pred[u], ..., s$ + * $p' = (v, pred[v], ..., s$ + + Pfade in $T$. Damit ist $u \sim v$ und $v \sim u$ in $T$ und damit (Transitivität) $u \sim v$ in T + + $\Rightarrow T$ ist zusammenhängend + +i) $T$ ist kreisfrei + + $T$ ist kreisfrei, da $T$ zusammenhängend und $|E'| = |V| + 1$ (siehe Übung) + +$$ +\tag*{$\Box$} +$$ diff --git a/school/di-ma/index.md b/school/di-ma/index.md index 1695e04..dd09236 100644 --- a/school/di-ma/index.md +++ b/school/di-ma/index.md @@ -11,3 +11,5 @@ subtitle: > - [2018-10-17 Wichtige Kombinatorische Probleme](20181017_1-wichtige_kombinatorische_probleme) - [2018-10-23 Zahlpartitionen](20181023_1-zahlpartitionen) - [2018-10-23 Bälle und Urnen](20181023_2-baelle_und_urnen) +- [2019-11-13 Directed Acyclic Graph](20181113_1-dag) +- [2019-11-13 Breitensuche](20181113_2-breitensuche)