\( \newcommand{\depth}{\textnormal{depth}} \newcommand{\height}{\textnormal{height}} \newcommand{\avgdepth}{\textnormal{avgdepth}} \newcommand{\floor}[1]{\left\lfloor #1 \right\rfloor} \newcommand{\ceil}[1]{\left\lceil #1 \right\rceil} \DeclareMathOperator*{\E}{\mathbb{E}} \newcommand{\pfrac}[2]{\left(\frac{#1}{#2}\right)} \newcommand{\R}{\mathbb{R}} \newcommand{\Z}{\mathbb{Z}} \newcommand{\X}{\mathcal{X}} \)

Wir wollen das Steuerungsprotokoll für eine kleine Mini-Drohne entwerfen. Sie soll acht Befehle verstehen:

forward, backward, turn left, turn right, up, down

Wir wollen nun die Menge $\X$ der Befehle binär codieren, also eine Funktion $C: \X \rightarrow \{0,1\}^*$ definieren. Da es sechs Befehle gibt und $6 \leq 8$ ist, bietet sich folgende Codierung an:

forward 000
backward 001
turn left 010
turn right 011
up 100
down 101

Wir können also jedes $x \in \X$ mit drei Bits codieren. Ist das optimal? Naja, wie wäre es denn mit folgendem Code:

forward 0
backward 1
turn left 00
turn right 01
up 10
down 11

Das Problem ist nun, dass wir Bitfolge wie 0010 nicht eindeutig decodieren können. Es könnte [turn left, up] sein, aber auch [turn left, backward, forward]. Welche Eigenschaft braucht $C$, um eindeutig decodierbar zu sein? Ganz klar: das Ende der Wörter muss eindeutig erkennbar sein. In anderen Worten: $C$ muss präfixfrei sein. Was heißt das?

Definition Sei $\Sigma$ ein Alphabet und $x, y \in \Sigma^*$. Das Wort $x$ ist ein Präfix von $y$, wenn es ein $u \in \Sigma^*$ gibt mit $y = xu$. Auf Deutsch gesagt: wenn $y$ mit $x$ beginnt. Wir schreiben $x \preceq y$.

Eine Funktion $C: \X \rightarrow \Sigma^*$ heißt präfixfrei wenn für alle verschiedenen $x, y \in \X$ auch $C(x) \not \preceq C(y)$ gilt.

Der Code im ersten Beispiel ist präfixfrei; der im zweiten nicht. Hier ist ein weiterer Code:

forward 000
backward 001
turn left 01
turn right 10
up 110
down 111

Um Codes und präfixfreie Codes über $\{0,1\}^*$ zu verstehen, bietet es sich an, die Menge $\{0,1\}^*$ aller endlichen Strings mit den Knoten des unendlichen Binärbaums zu identifizieren. Ich zeichne diesen Baum hier bis zur Tiefe 3:

Ganz einfach: die Wurzel ist $\epsilon$; ein Knoten $u \in \{0,1\}^*$ hat die zwei Kinder $u0$ und $u1$. Eine Codierung $C: \X \rightarrow \{0,1\}^*$ ist nun eine Funktion von $X$ in die Menge der Knoten dieses Baumes. Sie ist präfixfrei wenn kein Codewort $C(x)$ Vorfahre eines anderen $C(y)$ ist. Hier nochmal die drei Codes von oben:

Code 1: Ein Blockcode; alle Codewörter haben die gleiche Länge (3).
Code 2: Nicht präfixfrei.
Code 3: Präfixfrei

Und zum Spaß noch ein vierter Code:

Code 4: Auch präfixfrei

Übungsaufgabe Sei $\X$ eine Menge aus $n$ Elementen und $C: \X \rightarrow \{0,1\}^*$ ein präfixfreier Code. Zeigen Sie, dass es ein Codewort der Länge mindestens $\log_2 | \X|$ geben muss.

Welche Schranke bekommen Sie, wenn Sie nicht verlangen, dass $C$ präfixfrei ist, sondern nur injektiv (also dass keine zwei verschiedenen Elemente $x, y$ das gleiche Codewort zugewiesen bekommen)?

Erwartete Codelänge

Welcher der obigen Codes ist nun der Beste? Es ist ziemlich klar, dass Code 3 in jeder Hinsicht besser ist als Code 1: es gilt $|C_3(x)| \leq |C_1(x)|$, jedes Element braucht in $C_3$ also höchstens so viele Bits wie in $C_1$, und manche brauchen weniger (turn left und turn right). Wie vergleichen sich jedoch $C_3$ und $C_4$? Für das Wort forward ist $C_4$ besser; für backward sind beide gleich; für alle anderen ist $C_3$ besser. Wir können $C_3$ und $C_4$ also nicht direkt vergleichen. Wüssten wir allerdings, dass jeder zweite Befehl ein forward ist, so wäre $C_4$ womöglich der besser Code. Um solche verschiedenen Codes zu vergleichen, benötigen wir den Begriff der erwarteten Codelänge.

Definition Sei $\X$ eine endliche Menge, $P$ eine Wahrscheinlichkeitsverteilung über $\X$ und $C: \X \rightarrow \{0,1\}^*$ eine Codierung. Die erwartete Codelänge von $C$ für Verteilung $P$ ist

\begin{align} \E_{X \sim P} \left[|C(X)| \right] = \sum_{x \in \X} P(x) |C(x)| \ . \label{expected-codelength} \end{align}

Wenn wir $C : \X \rightarrow \{0,1\}^*$ als Baum $T$ darstellen, dann sprechen wir gerne von der erwarteten Tiefe des Baumes und schreiben $\avgdepth_P(T)$ für (\ref{expected-codelength}).

Beispiel. Nehmen wir eine Wahrscheinlichkeitsverteilung $P$ auf unserer Menge $\X$ der sechs Drohnenbefehle und vergleichen die beiden Codes $C_3$ und $C_4$.

$x$ $P(x)$ $C_3(x)$ $C_4(x)$
forward $0.4$ 000 0
backward $0.1$ 001 101
turn left $0.2$ 01 110
turn right $0.2$ 10 111
up $0.05$ 110 1000
down $0.05$ 111 1001

Die erwartete Codelänge von $C_3$ für Verteilung $P$ ist

\begin{align*} 0.4 \times 3 + 0.1 \times 3 + 0.2 \times 2 + 0.2 \times 2 + 0.05 \times 3 + 0.05 \times 3 = 2.6 \end{align*}

Für $C_4$ erhalten wir

\begin{align*} 0.4 \times 1 + 0.1 \times 3 + 0.2 \times 3 + 0.2 \times 3 + 0.05 \times 4 + 0.05 \times 4 = 2.3 \end{align*}

Für Verteilung $P$ ist $C_4$ also besser als $C_3$.

Übungsaufgabe Finden Sie eine Verteilung $Q$ auf $\X$, für die $C_3$ besser ist als $C_4$.

Optimale Codes: Huffman-Coding

Wenn wir nun eine Verteilung $P$ gegeben haben, wie können wir den für $P$ optimalen Code berechnen? Dies geht erstaunlich einfach mit einem Greedy-Algorithmus, dem Huffman-Coding.

def Huffman ($\X$: eine endliche Menge, $P$: eine Verteilung auf $\X$):
  1. Initialisierung. Erschaffe für jedes $x \in \X$ einen Baum $T_x$, der nur aus einem Wurzelknoten besteht, welcher selbst $x$ ist. Das Gewicht von $T_x$ sei $w(T_x) := P(x)$. Sei $\mathcal{T}$ die Menge dieser Bäume.
  2. while $|\mathcal{T}| \gt 1$:
    1. Wähle zwei Bäume $T_0, T_1 \in \mathcal{T}$ mit den kleinsten Gewichten $w(T_0), w(T_1)$.
    2. Erschaffe einen Binärbaum $T$ mit einem neuen Wurzelknoten $u$ und linkem Teilbaum $T_0$ und rechtem Teilbaum $T_1$.
    3. Setze $w(T) := w(T_0) + w(T_1)$.
    4. Beschrifte die Kante von $u$ zu $T_0$ mit $0$ und die nach $T_1$ mit $1$.
  3. Nun hat $\mathcal{T}$ die Größe $1$, also $\mathcal{T} =\{T\}$.
  4. Die Blätter von $T$ sind genau die Elemente $x \in X$.
  5. Setze $C(x) := $ die Folge von Beschriftungen entlang des Pfades von der Wurzel zum Blatt $x$
  6. return $C$

Hier ein Beispiellauf mit unserer Menge $\{$forward, backward, turn left, turn right, up, down$\}$ und der Wahrscheinlichkeitsverteilung $P$.

Theorem Der Code $C$, den der Huffman-Algorithmus findet, ist optimal, d.h. hat die kürzeste erwartete Codelänge aller präfixfreien Codes für $\X$ und Verteilung $P$.

Beweis. Wir verwenden Induktion über $n := |\mathcal{X}|$. Wenn $n=1$ ist, dann terminiert Huffman, ohne die while-Schleife auch nur ein einziges Mal durchlaufen zu haben. $T$ ist ein Baum, der nur aus der Wurzel besteht, das einzige Codewort ist $\epsilon$, die erwartete Codelänge ist somit $0$, was offensichtlich optimal ist.

Wenn $n \geq 2$ ist, dann seien $x_0, x_1 \in \mathcal{X}$ die beiden Elemente kleinster Wahrscheinlichkeit, die in Zeile 3.1 im ersten Schleifendurchlauf ausgewählt werden. Wir bauen nun eine neue Wahrscheinlichsverteilung, indem wir $x_0$ und $x_1$ verschmelzen. Formal: Sei $y$ ein neues Element und sei $\mathcal{Y} := \mathcal{X} \cup \{y\} \setminus \{x_0, x_1\} $. Wir definieren eine Wahrscheinlichkeitsverteilung $Q$ auf $\mathcal{Y}$ via

\begin{align*} Q(z) & := \begin{cases} P(x_0) + P(x_1) & \textnormal{ falls $z = y$,} \\ P(z) & \textnormal{ sonst.} \end{cases} \end{align*}

Die Mengen $\mathcal{Y}$ und die Verteilung $Q$ ist das, was Hufmann zu Beginn des zweiten Schleifendurchlaufs "sieht". Nach Induktion findet Hufmann optimalen Code/Binärbaum $T$ für $(\mathcal{Y}, Q)$. In diesem Baum $T$ gibt es ein Blatt $y$. Sei $S$ der Baum, der entsteht, wenn wir $y$ die zwei Kinder $x_0$ und $x_1$ hinzufügen. $S$ ist genau der Baum, mit den Huffman in Zeile 5 endet.

Behauptung: $S$ ist optimal für $(\mathcal{X}, P)$.

Beweis: Wir betrachten die erwartete Tiefe von $S$ und $T$. Die Tiefe eines zufälligen Elements $x \in \mathcal{X}$ ist gleich in $S$ und $T$, außer, wenn es sich um die "kollabierten" Elemente $x_0, x_1$ handelt. In diesem Falle ist sie $\depth(y,T)$ plus eins, weil wir ja noch die Kante von $y$ nach $x$ gehen müssen. Formal:

\begin{align*} \avgdepth_P(S) & = \sum_{x \in \mathcal{X}} P(x) \depth(x, S) \\ & = \sum_{z \in \mathcal{X} \setminus \{x_0, x_1\}} P(z) \depth(z,S) + P(x_0) \depth(x_0,S) + P(x_1) \depth(x_1,S) \\ & = \sum_{z \in \mathcal{Y}} Q(z) \depth(z,T) - Q(y) \depth(y,T) \\ & \quad + P(x_0) (\depth(y,T)+1) + P(x_1) (\depth(y,T)+1) \\ & = \avgdepth_Q(T) + P(x_1) + P(x_0) \end{align*}

Nach Induktion ist $\avgdepth_Q(T)$ optimal für $(\mathcal{Y}, Q)$. Sei nun $S'$ ein optimaler Baum für $(\mathcal{X}, P)$. Seien $v$ ein tiefstes Blatt in $S'$. Da $S'$ ein vollständiger Binärbaum ist, hat $v$ einen Geschwisterknoten $w$, der auch ein Blatt ist. Den Elternknoten von $v$ und $w$ nennen wir $y$. Was geschieht, wenn wir $v$ mit $x_0$ vertauschen? Da $v$ mindestens so tief ist wie $x_0$ und mindestens so häufig, kann die Vertauschung die erwartete Codelänge nur verringern; analog, wenn wir $w$ mit $x_1$ vertauschen. Nach Vertauschung erhalten wir einen neuen Baum, dessen erwartete Codelänge höchstens die von $S'$ ist; dieser ist also auch optimal. Wir nehmen nun also an, dass $S'$ optimal ist und $x_0, x_1$ Geschwisterblätter in $S'$ sind mit Elternknoten $y$. Sei $T'$ der Baum, der ensteht, wenn wir $x_0$ und $x_1$ entfernen. $T'$ ist ein Baum mit Blättermenge $\mathcal{Y}$, und nach ähnlicher Rechnung wie oben gilt

\begin{align*} \avgdepth_P(S') = \avgdepth_Q(T') + P(x_1) + P(x_0) \ . \end{align*}

Nun gilt

\begin{align*} \avgdepth_P(S) & = \avgdepth_Q(T) + P(x_1) + P(x_0) \tag{Rechnung oben} \\ & \leq \avgdepth_Q(T') + P(x_1) + P(x_0) \tag{$T$ ist optimal für $(\mathcal{Y}, Q)$} \\ & = \avgdepth_P(S') \ . \end{align*}

Die $S$ ist also gleich gut oder besser als $S'$ und ist somit auch optimal. \(\square\)

Somit sehen wir: der Hufmman-Algorithmus findet den optimalen präfixfreien Code für eine gegebene Wahrscheinlichkeitsverteilung. In den nächsten Kapiteln werden wir sehen, wie sich das zur Entropie verhält, einem fundamentalen Komplexitätsmaß von Wahrscheinlichkeitsverteilungen.