15 Optimales Kodieren Es soll ein optimaler Kodierer C(T ) entworfen werden, welcher eine Information (z.B. Text T ) mit möglichst geringer Bitanzahl eindeutig überträgt. Die Anforderungen an den optimalen Kodierer C(T ) sind: • sollte schnell kodieren • sollte eindeutig dekodieren (präx-frei) • minimale Kodelänge 15.1 Nötige Denitionen Als Beispiel soll der Text 'SUSANNE' kodiert werden. Folgende Denitionen werden benötigt: • T = 'SUSANNE' ist der zu kodierende Text (im allg. eine Information, welche kodiert werden sollte) • Z = {S, U, A, N, E} das Alphabet • |Z| = 5 ist die Gröÿe des Alphabets • fi ist die Auftrittsfrequenz. z.B.: fS = 2, fU = 1 • pi ist die Auftrittswahrscheinlichkeit - z.B.: pS = 72 , oder pU = 1 7 • Die Entropie H(T ) (Pseudoeinheit 'bit') ist die eigentliche Information, die der Text T pro Zeichen enthält: H(T ) = − |Z| X pj · log2 pj j=1 Wenn man den Text 'SUSANNE' naiv kodiert, dann benötigt man 3 Bits pro Buchstabe. Für den ganzen Text benötigt man 3 · 7 = 21 Bits. Die Entropie (der eigentliche Informationsgehalt) beträgt aber nur 2.24 Bits pro Buchstabe, was auch die theoretische untere Grenze darstellt. 1 Idee: Zeichen die häuger vorkommen, werden mit weniger Bits belegt. Ein Problem, dass dabei auftritt, ist das Präx-Problem. Damit der Kode eindeutig interpretierbar bleibt, darf kein Buchstabe kodiert ein Präx eines anderen Buchstaben sein. Zum Beispiel wenn C(x1 ) = 10 für 'S' und C(x2 ) = 100 für 'A' gegeben wäre, dann wäre das Kodestück ...100... nicht eindeutig dekodierbar!1 15.2 Darstellung des Kodierers Mit der Darstellung des Kodieres (und gleichzeitig des Dekodierers) als Binärbaum kann man Präxfreiheit garantieren. Die Datenstruktur hat dabei folgende Eigenschaften: • Binärbaum (sog. Kodebaum) • Werte sind blattorientiert (daher präxfrei) • Die Wortlänge entspricht der Astlänge li Wir suchen jenen Codebaum, der die Codelänge L(C) = Pn i=1 fi li minimiert. 15.3 Eigenschaften von optimalen Codebäumen Bevor wir einen Algorithmus zur Erzeugung eines optimalen Codebaums angeben, betrachten wir zunächst einige Eigenschaften eines optimalen Codebaums. 1. Der optimale Codebaum ist ein voller Binärbaum (d.h., jeder Knoten ist ein Blatt oder hat genau 2 Söhne). Beweis: Sei C ein Codebaum, der einen inneren Knoten k mit Grad 1 besitzt. Dann kann man daraus durch Löschen von k einen Baum C 0 mit einer kleineren Codelänge erzeugen: X L(C 0 ) = L(C) − fi · 1 ⇒ L(C 0 ) < L(C) i∈T (k) | {z >0 } T (k) ist dabei die Menge aller zu codierenden Zeichen (Blätter) unterhalb von k. Durch Löschen des Knotens k (Anhängen des einzigen Unterbaumes an seinen Vater) wird die Länge aller Wörter in T (k) um 1 verkürzt. 1 In der Literatur wird oft der Begri 'prex codes' verwendet. Damit sind aber genau präx-freie Kodes gemeint sind. 2 2. Seltene Zeichen sind tiefer im Baum als häuge (fj > fk ⇒ lj ≤ lk ). Beweis: Sei C optimal, aber ∃j, k : fj > fk , lk < lj . Sei C 0 ein Code bei dem die Wörter fur j und k vertauscht sind. Wenn C optimal ist, dann L(C 0 ) ≥ L(C) und daher 0 ≤ L(C 0 ) − L(C) X X = fi li0 − fi li i i = fj lj0 + fk lk0 − fj lj − fk lk = fj lk + fk lj − fj lj − fk lk = (lk − lj ) (fj − fk ) < 0, | {z } | {z } <0 >0 was einen Widerspruch darstellt. C kann daher nicht optimal sein. 3. Es existiert ein optimaler Codebaum, bei dem die zwei seltensten Zeichen Geschwister sind. Beweis: Sei f1 ≥ f2 ≥ . . . ≥ fn , d.h., seien xn , xn−1 die zwei seltensten Zeichen (Anm.: es kann mehrere solche Zeichen geben). xn besitzt das längste Codewort (ln ≥ li , ∀i), denn gäbe es ein Wort xi mit li > ln würde ein Vertauschen von xi und xn einen kürzeren Code liefern. Dann gilt: (a) xn muss einen Bruder besitzen, da der Binärbaum voll ist, und (b) dieser Bruder muss ein Blatt sein, denn wäre es ein innerer Knoten, gäbe es ein Zeichen xi mit li > ln (Widerspruch). Sei dieses Blatt xj . Entweder xj = xn−1 oder xj 6= xn−1 . Falls xj 6= xn−1 , kann man xj und xn−1 vertauschen, ohne L(C) zu verschlechtern: L(C 0 ) − L(C) = X fi li0 − X fi li i i = fn−1 lj + fj ln−1 − fn−1 ln−1 − fj lj = (fn−1 − fj ) (lj − ln−1 ) ≤ 0. {z } | {z } | ≤0 ≥0 15.4 Human Die Methode nach Human liefert garantiert einen optimalen Kodebaum. Mit folgender Vorgangsweise wird der Kodebaum konstruiert: • Erstelle einen 'Wald' mit jeweils einen Baum pro Zeichen. • Suche die beiden Bäume mit den kleinsten Wahrscheinlichkeiten und ver- binde sie zu einen neuen Baum, welche nun die Summe der Wahrscheinlichkeiten der Unterbäume besitzt. • Wiederhole den Vorgang, bis nur noch ein Baum übrig ist. 3 15.4.1 Implementierung Der Human-Algorithmus kann sehr eektiv mit einer Warteschlange Q mit Prioritäten implementiert werden, und zwar mit der Datenstruktur Halde. Dabei wird invers geordnet - d.h. das Minimum liegt an der Wurzel der Halde. Dem Algorithmus wird das Alphabet Z mit den zugehörigen Auftrittsfrequenzen fi s übergeben. HUFFMAN (Z,f) 1: n←|Z| 2: INIT_Q (Z) 3: FOR i←1 TO (n-1) 4: z←NEUER_KNOTEN 5: LINKS(z) ← MINIMUM(Q), ENTFERNE_MIN 6: RECHTS(z)← MINIMUM(Q), ENTFERNE_MIN 7: f(z) ← f(x)+f(y) 8: EINFUEGEN(Q,z) 9: RETURN MINIMUM(Q) Analyse: Alle Operationen der Warteschlange mit Prioritäten (mit einer Halde implementiert) können in O(log n) durchgeführt werden. Dabei werden sie innerhalb der Schleife n − 1 mal aufgerufen, d.h. T (n) = O(n · log n). 15.4.2 Beweis der Optimalität von Human Sei Z = {x1 , x2 , . . . , xn } das zu kodierende Alphabet mit den Auftrittswahrscheinlichkeiten f1 ≥ f2 ≥ . . . ≥ fn . Der Human-Algorithmus bestimmt den Codebaum für Z aus dem Codebaum für Z 0 = Z \ {xn−1 , xn } ∪ {w}, mit f (w) = fn−1 + fn . Der Beweis erfolgt mittels vollständiger Induktion: • Der Human-Algorithmus liefert oensichtlich einen optimalen Codebaum für |Z| = 2. • zu zeigen: Ist B 0 ein optimaler Codebaum für Z 0 , ist B auch ein optimaler Codebaum für Z . Es gilt ln−1 li = li0 i = 1, . . . , n − 2 = ln = l(w) + 1 4 Für die Codelänge von B ergibt sich damit L(B) = n X fi li = fn ln + fn−1 ln−1 + n−2 X i=1 fi li i=1 = (fn + fn−1 )(l(w) + 1) + n−2 X fi li0 i=1 = f (w)l(w) + f (w) + n−2 X fi li0 i=1 0 = f (w) + L(B ). Sei B nicht optimal, d.h., ∃B̃ : L(B̃) < L(B), und B̃ hat xn , xn−1 als Geschwister. Daraus kann man wiederum einen Baum B̃ 0 erzeugen, durch Ersetzen von xn , xn−1 durch w. Dann gilt: L(B̃) < L(B) f (w) + L(B̃ 0 ) < f (w) + L(B 0 ) L(B̃ 0 ) < L(B 0 ), was aber ein Widerspruch zur Annahme der Optimalität von B 0 ist. 5