algo-cheatsheet/sheet.tex

430 lines
13 KiB
TeX
Raw Permalink Normal View History

2022-08-31 01:30:25 +02:00
\documentclass[11pt, a4paper, twoside]{article}
\usepackage[
a4paper,
headsep=5mm,
footskip=0mm,
top=12mm,
left=10mm,
right=10mm,
bottom=10mm
]{geometry}
2022-08-31 01:30:25 +02:00
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{multicol}
\usepackage[noend]{algorithm2e}
\usepackage[utf8]{inputenc}
\usepackage{fancyhdr}
\usepackage{hyperref}
\hypersetup{
colorlinks=true,
linkcolor=blue,
filecolor=magenta,
urlcolor=cyan,
pdftitle={Overleaf Example},
pdfpagemode=FullScreen,
}
2022-08-31 01:30:25 +02:00
\setlength{\algomargin}{0pt}
\begin{document}
\pagestyle{fancy}
\fancyhead{}
\fancyhead[L]{Algorithmen 1}
\fancyhead[R]{Gero Beckmann - \url{https://github.com/Geronymos/algo-cheatsheet}}
\fancyfoot{}
\fancyfoot[R]{\thepage}
2022-08-31 01:30:25 +02:00
\section{Laufzeit}
\hspace*{-.5cm}
\begin{tabular}{ l l l l }
Notations & Asymptotischer Vergleich & Formale Definition & Grenzen \\
$f(n) \in \omega(g(n))$&
$f(n)$ wächst schneller als $g(n)$ &
$\forall c \exists n_0 \forall n > n_0 f(n) > c \cdot g(n)$ &
$$$\lim\sup\limits_{n \rightarrow \infty}\frac{f}{g} = \infty$$$ \\
$f(n) \in \Omega(g(n))$ &
$f(n)$ wächst min. so schnell wie $g(n)$ &
$\exists c \exists n_0 \forall n > n_0 c \cdot f(n) \leq g(n)$ &
$$$0 < \liminf\limits_{n \rightarrow \infty}\frac{f}{g} \leq \infty$$$ \\
\( f(n) \in \Theta(g(n)) \) &
$f(n)$ und $g(n)$ wachsen gleich schnell &
$f(n) \in \mathcal{O}(g(n)) \wedge f(n) \in \Omega(g(n))$ &
$$$0 < \lim\limits_{n \rightarrow \infty}\frac{f}{g} < \infty$$$ \\
\( f(n) \in \mathcal{O}(g(n)) \) &
$f(n)$ wächst max. so schnell wie $g(n)$ &
$\exists c \exists n_0 \forall n > n_0 f(n) \leq c \cdot g(n)$ &
$$$0 \leq \limsup\limits_{n \rightarrow \infty}\frac{f}{g} < \infty$$$ \\
\( f(n) \in o(g(n)) \) &
$f(n)$ wächst langsamer als $g(n)$ &
$\forall c \exists n_0 \forall n > n_0 c \cdot f(n) < g(n)$ &
$$$\lim\limits_{n \rightarrow \infty} \frac{f}{g} = \infty$$$ \\
\end{tabular}
\subsection{Vergleich}
\begin{tabular}{|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|c|}
$1$ & $\log^*n$ & $\log n$ & $\log^2n$ & $\sqrt[3]{n}$ &
$\sqrt{n}$ & $n$ & $n^2$ & $n^3$ & $n^{\log n}$ &
$2^{\sqrt{n}}$ & $2^n$ & $3^n$ & $4^n$ & $n!$ & $2^{n^2}$
\end{tabular}
\begin{multicols}{3}
\subsubsection*{Transitivität}
$f_1(n) \in \mathcal{O}(f_2(n)) \wedge f_2(n) \in\mathcal{O}(f_3(n))$ \\
$\Rightarrow f_1(n) \in \mathcal{O}(f_3(n))$
\subsubsection*{Summen}
$f_1(n) \in \mathcal{O}f_3(n)) \wedge f_2(n) \in \mathcal{O}(f_3(n))$ \\
$\Rightarrow f_1(n) + f_2(n) \in \mathcal{O}(f_3(n))$
\subsubsection*{Produkte}
$f_1(n) \in \mathcal{O}(g_1(n)) \wedge f_2(n) \in \mathcal{O}(g_2(n))$ \\
$\Rightarrow f_1(n) \cdot f_2(n) \in \mathcal{O}(g_1(n) \cdot g_2(n))$
\columnbreak
\subsection{Master-Theorem}
Sei $T(n) = a \cdot T(\frac{n}{b}) + f(n)$ mit $f(n) \in \Theta(n^c)$ und i
$T(1) \in \Theta(1)$. Dann gilt
$
T(n) \in \begin{cases}
\Theta(n^c) &\text{wenn } a < b^c, \\
\Theta(n^c \log n) &\text{wenn } a = b^c, \\
\Theta(n^{\log_b(a)}) &\text{wenn } a > b^c.
\end{cases}
$
\subsubsection{Monome}
\begin{itemize}
\item $a \leq b \Rightarrow n^a \in \mathcal{O}(n^b)$
\item $n^a \in \Theta(n^b) \Leftrightarrow a = b$
\item $\sum_{v \in V}deg(v) = \Theta(m)$
\item $\forall n \in \mathbb{N}: \sum^n_{k=0}k = \frac{n(n+1)}{2}$
\item $
2022-08-31 12:52:46 +02:00
\sum^b_{i=a}c^i \in \begin{cases}
2022-08-31 01:30:25 +02:00
\Theta(c^a) &\text{wenn } c < 1, \\
\Theta(c^b) &\text{wenn } c > 1, \\
\Theta(b-a) &\text{wenn } c = 1.
\end{cases}
$
\item $\log(ab) = \log(a) + \log(b)$
\item $\log(\frac{a}{b}) = \log(a) - \log(b)$
\item $a^{\log_a(b)} = b$
\item $a^x = e^{ln(a) \cdot x}$
\item $\log(a^b) = b \cdot \log(a)$
\item $\log_b(n) = \frac{\log_a(n)}{\log_a(b)}$
\end{itemize}
%\subsubsection{Konstante Faktoren}
%
%$a \cdot f(n) \in \Theta(f(n))$
\end{multicols}
\begin{minipage}{0.7\textwidth}
\section{Sortieren}
\begin{tabular}[t]{c || c | c | c | c}
Algorithmus & best case & average & worst & Stabilität \\
\hline
Insertion-Sort &
$\mathcal{O}(n)$ & $\mathcal{O}(n^2)$ & $\mathcal{O}(n^2)$ & stabil\\
Bubble-Sort &
$\mathcal{O}(n)$ & $\mathcal{O}(n^2)$ & $\mathcal{O}(n^2)$ & stabil\\
Merge-Sort &
$\mathcal{O}(n\log n)$ & $\mathcal{O}(n\log n)$ & $\mathcal{O}(n\log n)$ & stabil\\
Quick-Sort &
$\mathcal{O}(n \log n)$ & $\mathcal{O}(n\log n)$ & $\mathcal{O}(n\log n)$ & i.A. nicht stabil\\
Heap-Sort &
$\mathcal{O}(n\log n)$ & $\mathcal{O}(n\log n)$ & $\mathcal{O}(n\log n)$ & nicht stabil\\
\hline
Bucket-Sort &
$\Theta(n+m)$ & $\Theta(n+m)$ & $\Theta(n+m)$ &
stabil $e \in [0, m)$\\
Radix-Sort &
$\Theta(c \cdot n)$ & $\Theta(c\cdot n)$ & $\Theta(c\cdot n)$ &
2022-08-31 12:52:46 +02:00
stabil $e \in [0, n^c)$\\
2022-08-31 01:30:25 +02:00
\end{tabular}
\end{minipage}
\hfill
\begin{minipage}{0.3\textwidth}
\subsection{Heaps}
\begin{tabular}[t]{c || c}
Bin.-Heap & Laufzeit \\
\hline
push(x) & $\mathcal{O}(\log n)$ \\
popMin() & $\mathcal{O}(\log n)$ \\
2022-08-31 13:14:22 +02:00
decPrio(x, x') & $\mathcal{O}(\log n)$ \\
2022-08-31 01:30:25 +02:00
build([$\mathbb{N}$; n]) & $\mathcal{O}(n)$
\end{tabular}
\begin{itemize}
\item linkes Kind: $2v + 1$
\item rechts Kind: $2v + 2$
\item Elternknoten: $ \lfloor \frac{v - 1}{2} \rfloor $
\end{itemize}
\end{minipage}
\begin{multicols}{2}
\section{Datenstrukturen}
\subsection{Listen}
\begin{tabular}{c || c | c | c || c}
Operation & DLL & SLL & Array & Erklärung(*) \\
\hline
first & 1 & 1 & 1 & \\
last & 1 & 1 & 1 & \\
insert & 1 & 1* & n & nur insertAfter \\
remove & 1 & 1* & n & nur removeAfter \\
pushBack & 1 & 1 & 1* & amortisiert \\
pushFront & 1 & 1 & n & \\
popBack & 1 & n & 1* & amortisiert \\
popFront & 1 & 1 & n & \\
concat & 1 & 1 & n & \\
splice & 1 & 1 & n \\
findNext & n & n & n
\end{tabular}
\subsection{Hash-Tabelle}
$\mathcal{H}$ heißt \textbf{universell}, wenn für ein zufälliges gewähltes
$h \in \mathcal{H}$ gilt: $U \rightarrow \{0, ..., m-1\}$ \\
2022-08-31 13:14:22 +02:00
$\forall k, l \in U, k \neq l: Pr[h(k) = h(l)] = \frac{1}{m}$ \\
2022-08-31 01:30:25 +02:00
$h_{a,b}(k) = ((a\cdot k + b) \mod p) \mod m$
\subsection{Graphen}
\begin{tabular}{c || c}
Algorithmus & Laufzeit \\
\hline
BFS/DFS & $\Theta(n+m)$\\
topoSort & $\Theta(n)$\\
Kruskal & $\Theta(m \log n)$\\
Prim & $\Theta((n+m)\log n)$ \\
Dijksta & $\Theta((n + m) \log n)$\\
Bellmann-Ford & $\Theta(nm)$\\
Floyd-Warshall & $\Theta(n^3)$ \\
\end{tabular}
\end{multicols}
\newpage
\begin{multicols}{2}
\subsubsection{DFS}
\begin{tabular}{c || c | c}
Kante & DFS & FIN \\
\hline
Vorkante & klein $\rightarrow$ groß & groß $\rightarrow$ klein \\
Rückkante & groß $\rightarrow$ klein & klein $\rightarrow$ groß \\
Querkante & groß $\rightarrow$ klein & groß $\rightarrow$ klein \\
Baumkante & klein $\rightarrow$ groß & groß $\rightarrow$ klein \\
\end{tabular}
\subsection{Bäume}
\subsubsection{Heap}
Priorität eines Knotens $\geq (\leq)$ Priorität der Kinder.
\textbf{BubbleUp}, \textbf{SinkDown}. \textbf{Build} mit \textbf{sinkDown}
beginnend mit letztem Knoten der vorletzten Ebene weiter nach oben.
\textbf{decPrio} entweder updaten, Eigenschaft wiederherstellen; löschen,
mit neuer Prio einfügen oder Lazy Evaluation.
\subsubsection{(ab)-Baum}
2022-08-31 13:14:22 +02:00
Balanciert. \textbf{find}, \textbf{insert}, \textbf{remove} in
$\Theta(log n)$. Zu wenig Kinder: \textbf{rebalance} / \textbf{fuse}.
2022-08-31 01:30:25 +02:00
Zu viele Kinder: \textbf{split}.
Linker Teilbaum $\leq$ Schlüssel k $<$ rechter Teilbaum
Unendlich-Trick, für Invarianten.
\subsection{Union-Find}
Rang: höhe des Baums, damit ist die Höhe h mind. $2^h$ Knoten, h $\in
\mathcal{O}(\log n)$.
Union hängt niedrigen Baum an höherrängigen Baum. Pfadkompression hängt alle
Knoten bei einem \textbf{find} an die Wurzel.
\columnbreak
\section{Amortisierte Analyse}
\subsection{Aggregation}
Summiere die Kosten für alle Operationen. Teile Gesamtkkosten durch Anzahl
Operationen.
\subsection{Charging}
2022-08-31 13:14:22 +02:00
Verteile Kosten-Tokens von teuren zu günstigen Operationen (Charging). Zeige:
2022-08-31 01:30:25 +02:00
jede Operation hat am Ende nur wenige Tokens.
\subsection{Konto}
Günstige Operationen bezahlen mehr als sie tatsächlich kosten (ins Konto
einzahlen). Teure Operationen bezahlen tatsächliche Kosten zum Teil mit
Guthaben aus dem Konto. \textbf{Beachte: Konto darf nie negativ sein!}
\subsection{Potential (Umgekehrte Kontomethode)}
Definiere Kontostand abhängig vom Zustand der Datenstruktur
(Potentialfunktion)
amortisierten Kosten = tatsächliche Kosten
$+ \Phi(S_\text{nach}) -\Phi(S_\text{vor})$
\end{multicols}
\section{Pseudocode}
\scriptsize
\begin{minipage}{.25\linewidth}
\begin{algorithm}[H]
DFS(Graph G, Node v) \\
mark v \\
dfs[v] := dfsCounter++ \\
low[v] := dfs[v] \\
\For{u $\in$ N(v)}{
\eIf{not marked u}{
dist[u] := dist[v] + 1 \\
par[u] := v \\
DFS(G, u) \\
low[v] := min(low[v], low[u]) \\
}{low[v] := min(low[v], dfs[u])}
}
fin[v] := fin++ \\
\end{algorithm}
\end{minipage}
\begin{minipage}{.25\linewidth}
\begin{algorithm}[H]
topoSort(Graph G) \\
fin := [$\infty$; n] \\
curr := 0 \\
\For{Node v in V}{
\If{v is colored}{DFS(G,v)}
}
return V sorted by decreasing fin \\
\end{algorithm}
\end{minipage}
\begin{minipage}{.25\linewidth}
\begin{algorithm}[H]
Kruskal(Graph G) \\
U := Union-Find(G.v) \\
PriorityQueue Q := empty \\
\For{Edge e in E}{Q.push(e, len(e))}
\While{Q $\neq \emptyset$}{
e := Q.popMin() \\
\If{U.find(v) $\neq$ U.find(u)}{
L.add(e) \\
U.union(v, u) \\
}
}
\end{algorithm}
\end{minipage}
\begin{minipage}{.25\linewidth}
\begin{algorithm}[H]
Prim(Graph G) \\
Priority Queue Q := empty \\
p := [0; n] \\
\For{Node v in V}{
Q.push(v, $\infty$) \\
}
\While{Q $\neq \emptyset$}{
u := Q.popMin() \\
\For{Node v in N(u)}{
\If{v $\in$ Q $\wedge$ (len(u, v) $<$ Q.prio(v))}{
p[v] = u \\
Q.decPrio(v, len(u, v) \\
}
}
}
\end{algorithm}
\end{minipage}
\begin{minipage}{.25\linewidth}
\begin{algorithm}[H]
BFS(Graph G, Start s, Goal z) \\
Queue Q := empty queue \\
Q.push(s) \\
s.layer = 0 \\
\While{Q $\neq \emptyset$}{
u := Q.pop() \\
\For{Node v in N(u)}{
\If{v.layer = $-\infty$}{
Q.push(v) \\
v.layer = u.layer + 1
}
\If{v = z}{
return z.layer
}
}
}
\end{algorithm}
\end{minipage}
\begin{minipage}{.25\linewidth}
\begin{algorithm}[H]
Dijkstra(Graph G, Node s) \\
d := [$\infty$; n] \\
d[s] := 0 \\
PriorityQueue Q := empty priority queue \\
\For{Node v in V}{
Q.push(v, d[v])
}
\While{Q $\neq \emptyset$}{
u := Q.popMin() \\
\For{Node v in N(u)}{
\If{d[v] $>$ d[u] + len(u, v)}{
d[v] := d[u] + len(u, v) \\
Q.decPrio(v, d[v]) \\
}
}
}
\end{algorithm}
\end{minipage}
\begin{minipage}{.25\linewidth}
\begin{algorithm}[H]
BellManFord(Graph G, Node s) \\
d := [$\infty$, n] \\
d[s] := 0 \\
\For{n-1 iterations}{
\For{(u, v) $\in$ E}{
\If{d[v] $>$ d[u] + len(u, v)}{
d[v] := d[u] + len(u, v)
}
}
}
\For{(u, v) $\in$ E}{
\If{d[v] $>$ d[u] + len(u, v)}{
return negative cycle
}
}
return d
\end{algorithm}
\end{minipage}
\begin{minipage}{.25\linewidth}
\begin{algorithm}[H]
FloydWarshall(Graph G) \\
D := [$\infty$, n $\times$ n] \\
\For{(u, v) $\in$ E}{D[u][v] := len(u, v)}
\For{v $\in$ V}{D[v][v] := 0}
\For{i $\in 1,...,n$}{
\For{(u,v) $\in V \times V$}{
D[u][v] := min(D[u][v], D[u][$v_i$] + D[$v_i$][v]) \\
}
}
return D
\end{algorithm}
\end{minipage}
\end{document}