Wiederholung Erweiterte Huffman-Kodierung Dynamische Huffman-Kodes Arithmetische Kodes Fakultät für Informatik Lehrstuhl 2 Vorlesung Effiziente Algorithmen und Komplexitätstheorie Sommersemester 2008 Ingo Wegener; Vertretung: Carsten Witt 10. Juli 2008 Vorlesung am 14.07. (nächste Woche): Raum E04/E05 1/21 Wiederholung Erweiterte Huffman-Kodierung Dynamische Huffman-Kodes Arithmetische Kodes Was bisher geschah • Datenkompression • Unterscheidung verlustfrei ↔ verlustbehaftet • Beschränkung auf verlustfrei • Präfixkodes als effiziente Darstellungsform • Existenz von Präfixkodes (Kraft/McMillan) • Informationstheoretisches Modell • Entropie als untere Schranke • 3 Algorithmen zur Erzeugung von Präfixkodes • Shannon-Algorithmus • Shannon-Fano-Algorithmus • Huffman-Algorithmus • Optimalität des Huffman-Algorithmus • Schranke 1 größer als Entropie • Verbesserung: Blockbildung (erweiterte Huffman-Kodierung) 2/21 Wiederholung Erweiterte Huffman-Kodierung Dynamische Huffman-Kodes Arithmetische Kodes Erweiterte Huffman-Kodierung: Wiederholung Beispiel: Σ = {a, b}, Prob(a) = 0,99, Prob(b) = 0,01 Idee: Zusammenfassung von je 3 Buchstaben zu einem Block Also: Σ3 = {aaa, aab, aba, baa, abb, bab, bba, bbb} Huffman-Kode:c(aaa) = 0, c(aab) = 100, c(aba) = 101, c(baa) = 110, c(abb) = 11100, c(bab) = 11101, c(bba) = 11110, c(bbb) = 11111 Erwartete Länge = 1,059998 Entropie H(Σ3 ) ≥ 0,242 Also: Redundanz ≤ 0,818, Kompression nur noch“ 338 % zu lang ” Vergleich der 3 Varianten: k 1 2 3 H(Σk ) 0,081 0,161 0,242 Lc (Σk ) 1,000 1,030 1,060 Lc (Σk )/k 1,000 0,515 0,353 Lc (Σk )/k − H(Σk ) 0,919 0,354 0,111 Lc (Σk )/k − H(Σ) 0,919 0,434 0,272 3/21 Wiederholung Erweiterte Huffman-Kodierung Arithmetische Kodes Dynamische Huffman-Kodes Erweiterte Huffman-Kodierung: Analyse (1/3) Beobachtung: Lc (Σk )/k = bei Blocklänge k erwartete Kodierungslänge eines Zeichens der erweiterten Huffman-Kodierung Theorem Lc (Σk )/k ≤ H(Σ) + 1/k. Beweis: genügt zu zeigen: H(Σk ) = k · H(Σ) (Induktion) Induktionsanfang (k = 1): klar Induktionsschritt: X H(Σk ) = Prob(s) · log s∈Σk = X X s ′ ∈Σ s ′′ ∈Σk−1 1 Prob(s) Prob(s ′ s ′′ ) · log 1 Prob(s ′ s ′′ ) 4/21 Wiederholung Erweiterte Huffman-Kodierung Dynamische Huffman-Kodes Arithmetische Kodes Erweiterte Huffman-Kodierung: Analyse (2/3) = X X Prob(s ′ s ′′ ) · log s ′ ∈Σ s ′′ ∈Σk−1 = X X 1 Prob(s ′ s ′′ ) Prob(s ′ ) Prob(s ′′ ) s ′ ∈Σ s ′′ ∈Σk−1 1 1 · log + log Prob(s ′ ) Prob(s ′′ ) X X = Prob(s ′ ) · Prob(s ′′ ) · log s ′′ ∈Σk−1 s ′ ∈Σ 1 Prob(s ′′ ) 1 Prob(s ′′ ) · + Prob(s ′ ) · log Prob(s ′ ) ′ ′′ k−1 s ∈Σ s ∈Σ ! X X = Prob(s ′′ )H(Σ) Prob(s ′ )H(Σk−1 ) + s ′ ∈Σ X X s ′′ ∈Σk−1 5/21 Wiederholung Erweiterte Huffman-Kodierung Arithmetische Kodes Dynamische Huffman-Kodes Erweiterte Huffman-Kodierung: Analyse (3/3) Also H(Σk ) = X ! Prob(s ′ )H(Σk−1 ) s ′ ∈Σ IV + X s ′′ ∈Σk−1 Prob(s ′′ )H(Σ) = H(Σk−1 ) + H(Σ) = (k − 1)H(Σ) + H(Σ) = kH(Σ) Problem: √ exponentieller Aufwand in k 6/21 Wiederholung Erweiterte Huffman-Kodierung Dynamische Huffman-Kodes Arithmetische Kodes Bestimmung des probabilistischen Modells Bisher: probabilistisches Modell vorausgesetzt Quelle erzeugt unabh. Ereignisse, hier Buchstaben s ∈ Σ = {s1 , . . . , sn } mit Auftrittswahrscheinlichkeiten Prob(s) für s ∈ Σ. Problem: i. Allg. für Texte verschiedene Wahrscheinlichkeiten Aufgabe: Wahrscheinlichkeiten/Häufigkeiten aus Text lernen Naiver Ansatz: Vorverarbeitung (Häufigkeiten vorab zählen) Vorverarbeitung einfach, aber eventuell doppelt aufwendig und nicht onlinefähig (Eingabe muss zweimal gelesen werden) Gewünscht: Wkten. während der Kodierung lernen 7/21 Wiederholung Erweiterte Huffman-Kodierung Dynamische Huffman-Kodes Arithmetische Kodes Dynamische Huffman-Bäume Ansatz: Huffman-Baum während Kodierung aufgebaut, sogar Online-Übertragung des Kodes von Sender zu Empfänger Präfixkodebäume bei dyn. Huffman-Kodierung wie bisher: Buchstaben in Blättern wie bisher: Zahlen in allen Knoten wie bisher: jeder Knoten (außer Wurzel) hat Geschwist neu: Knoten enthalten absolute Häufigkeiten statt Wkten.; kumulierte Häufigkeiten für alle Buchstaben im Unterbaum • neu: Blatt mit Häufigkeitswert 0 für neue Buchstaben ( ⊥“) ” • neu: Knoten befolgen spezielle Sortierung • • • • Sortierung Ebenenweise von unten nach oben und von links nach rechts gelesen, sind die Häufigkeitswerte der Knoten monoton wachsend. 8/21 Wiederholung Erweiterte Huffman-Kodierung Dynamische Huffman-Kodes Arithmetische Kodes Dynamischer Huffman-Baum: Beispiel Komprimierter Text: aabcccbd 8 3 • Offensichtlich Präfixkodebaum 5 c • Zahlen = Häufigkeiten 2 der Buchstaben in den jeweiligen Unterbäumen 3 a 2 1 b 0 1 ⊥ d • Sortierung erfüllt: 011223358 monoton wachsend Ziel Baum effizient und online bei Sender und Empfänger aufbauen 9/21 Wiederholung Erweiterte Huffman-Kodierung Dynamische Huffman-Kodes Arithmetische Kodes Dynamischer Huffman-Baum: Aufbau Algorithmus von Faller/Gallager/Knuth (1985) 1 Start mit Blatt 0/⊥ 2 Verarbeite zu komprimierenden Text von links nach rechts; sei s das aktuelle Zeichen. (a) Wenn s noch nicht im Baum enthalten, dann ersetze 0/⊥-Blatt durch Baum mit Wurzel 1, linkem Sohn 0/⊥ und rechtem Sohn 1/s. Sende Kode von ⊥ und s unkomprimiert (z. B. ASCII) sonst sende Kode von s. (b) Inkrementiere die Häufigkeiten auf dem Weg vom Blatt mit s bis zur Wurzel. Wenn auf diesem Weg an Knoten Sortierung verletzt, tausche Knoten (samt Unterbäumen) mit dem in der Sortierung letztem Element zuvor gleicher Häufigkeit; setze Weg zur Wurzel von neuer Position des Knotens aus fort. Klar: Baum zugleich bei Sender und Empfänger aufzubauen 10/21 Wiederholung Erweiterte Huffman-Kodierung Arithmetische Kodes Dynamische Huffman-Kodes FGK-Algorithmus: Beispiel Text: aabcccbd Kode: ASCII(a)10ASCII(b)00ASCII(c)00111101100ASCII(d) 0 1 ⊥ 0 1 a ⊥ 2 3 0 2 2 Bemerkungen: Implementierung mit Laufzeit O(Kodelänge) möglich, 1 a a ⊥ Kodelänge ≤ 2S + t, t = Anzahl kodierter Buchstaben, 1 0 S optimale Kodelänge bei Vorwissen der Häufigkeiten 11/21 Wiederholung Erweiterte Huffman-Kodierung Dynamische Huffman-Kodes Arithmetische Kodes Arithmetische Kodes Beobachtung: lieber Zeichenfolgen statt einzelner Zeichen kodieren Ansatz: jeder Zeichenfolge ein Schild“ (tag) injektiv zuordnen ” Formal: c : Σ∗ → [0; 1[ injektiv Definiere für Σ = {s1 , . . . , sn } und (statische) Wkten. Prob(si ) F (k) := k X Prob(si ) (Partialsummen/Verteilungsfunktion) i =1 Partitioniere [0; 1[ in Intervalle [F (0); F (1)[, [F (1); F (2)[, . . . Zuordnung erster Buchstabe: si → i -tes Intervall [F (i − 1); F (i )[ Partitioniere i -tes Intervall proportional in |Σ| Intervalle Zuordnung zweiter Buchstabe: sj → j-tes Intervall von [F (i − 1); F (i )[ usw. 12/21 Wiederholung Erweiterte Huffman-Kodierung Arithmetische Kodes Dynamische Huffman-Kodes Beispiel Intervallschachtelung Beispiel: Σ = {s1 , s2 , s3 }, Wkten. (7/10, 1/10, 1/5), suche Kode für s3 s1 s2 1 1 0.94 0.912 s3 s2 s3 s2 s3 s2 s3 s2 s1 s1 s1 s1 0 0.8 0.8 0.808 Tag beliebig im Intervall, z. B. Mittelpunkt Ergebnis: verschiedene Texte → disjunkte Intervalle 13/21 Wiederholung Erweiterte Huffman-Kodierung Dynamische Huffman-Kodes Arithmetische Kodes Tag-Berechnung (Kodieren) Initial in [ℓ0 ; u0 [ mit ℓ0 = 0, u0 = 1 Nach x1 in [ℓ1 ; u1 [ mit ℓ1 = F (x1 − 1), u1 = F (x1 ) Nach x2 in [ℓ2 ; u2 [ mit ℓ2 = ℓ1 + (u1 − ℓ1 ) · F (x2 − 1), u2 = ℓ1 + (u1 − ℓ1 ) · F (x2 ) .. . Nach xi in [ℓi ; ui [ mit ℓi = ℓi −1 + (ui −1 − ℓi −1 ) · F (xi − 1), ui = ℓi −1 + (ui −1 − ℓi −1 ) · F (xi ) Dann: Tag für x1 . . . xk ist ℓk + (uk − ℓk )/2 = (ℓk + uk )/2 Also: effizient berechenbar (zumindest theoretisch) 14/21 Wiederholung Erweiterte Huffman-Kodierung Dynamische Huffman-Kodes Arithmetische Kodes Dekodieren Arithmetischen Kode c ∈ [0; 1[ dekodieren 1. ℓ0 := 0, u0 := 1, i := 1 2. Finde xi ∈ Σ, sodass c ∈ [F (xi − 1), F (xi )[. 3. ℓi = ℓi −1 + (ui −1 − ℓi −1 ) · F (xi − 1) ui = ℓi −1 + (ui −1 − ℓi −1 ) · F (xi ) 4. c := (c − ℓi )/(ui − ℓi ) 5. i := i + 1 6. Wenn noch nicht fertig, weiter bei 2. Klar: Korrektheit Klar: wenige Rechenoperationen (auf reellen Zahlen) Abbruch (Zeile 6) implementieren? Lösung: Länge mitsenden oder Endzeichen 15/21 Wiederholung Erweiterte Huffman-Kodierung Dynamische Huffman-Kodes Arithmetische Kodes Konkrete Implementierung Problem: reelle Zahlen Gewünscht: effiziente Kodierung Σ∗ → {0, 1}+ Zunächst zwecks Übersichtlichkeit: einzelnes Zeichen x ∈ Σ kodieren, ähnlich Shannon-Algorithmus Theorem Sei c : Σ∗ → [0, 1] ein arithmetischer Kode und sei für x ∈ Σ mit c(x) = (0,b(x)1 b(x)2 . . . )2 die Binärdarstellung von c(x) gegeben. Dann ist der Kode b(x)1 b(x)2 . . . b(x)ℓ(x) für ℓ(x) := 1 + ⌈− log Prob(x)⌉ eindeutig und eindeutig dekodierbar. Beweis 1. Eindeutigkeit zeigen Dazu: Zeige c(x)ℓ(x) = (0,b(x)1 b(x)2 . . . b(x)ℓ(x) )2 ∈ [F (x − 1), F (x)[. 16/21 Wiederholung Erweiterte Huffman-Kodierung Dynamische Huffman-Kodes Arithmetische Kodes Konkrete Implementierung: Eindeutigkeit Zeige: c(x)ℓ(x) = (0,b(x)1 b(x)2 . . . b(x)ℓ(x) )2 ∈ [F (x − 1), F (x)[. Klar: 0 ≤ c(x) − c(x)ℓ(x) < 2−ℓ(x) Wegen c(x) ∈ [F (x − 1); F (x)[ ist c(x)ℓ(x) < F (x). Definition liefert c(x) = F (x − 1) + Prob(x)/2. Also: c(x)ℓ(x) ≥ F (x − 1) + Prob(x)/2 − 2−ℓ(x) . Genügt zu zeigen: Prob(x)/2 ≥ 2−ℓ(x) . Dies folgt aus ℓ(x) = 1 + ⌈− log Prob(x)⌉. Fehlt noch: eindeutige Dekodierbarkeit 17/21 Wiederholung Erweiterte Huffman-Kodierung Dynamische Huffman-Kodes Arithmetische Kodes Konkrete Implementierung: eindeutige Dekodierbarkeit Zeige: b(x)1 b(x)2 . . . b(x)ℓ(x) ist Präfixkode. Betrachte si 6= sj . Wissen: c(sj )ℓ(sj ) und c(si )ℓ(si ) wegen Eindeutigkeit in disjunkten Intervallen [F (sj − 1); F (sj )[ und [F (si − 1); F (si )[ Annahme: c(sj )ℓ(sj ) ist Präfix von c(si )ℓ(si ) Dann: c(si ) ∈ [c(sj )ℓ(sj ) , c(sj )ℓ(sj ) + 2−ℓ(sj ) [ (wegen Übereinstimmung in ersten ℓ(sj ) Nachkommastellen) Wenn c(sj )ℓ(sj ) + 2−ℓ(sj ) < F (sj ), dann folgt wg. c(sj )ℓ(sj ) > F (sj − 1), dass c(si ) ∈ [F (sj − 1); F (sj )[ . Es ist c(sj )ℓ(sj ) + 2−ℓ(sj ) < c(sj ) + Prob(sj )/2 = F (sj ). √ 18/21 Wiederholung Erweiterte Huffman-Kodierung Dynamische Huffman-Kodes Arithmetische Kodes Erwartete Kodierungslänge der Implementierung Erinnerung: Buchstaben unabhängig Kodiere Wörter X = x1 x2 . . . xk auf gleiche Weise wie oben mit ℓ(X ) = 1 + ⌈log(1/Prob(X ))⌉ Bits Erwartete Länge X = Prob(X ) · ℓ(X ) X ∈Σk = 1 Prob(X ) 1 Prob(X ) · 2 + log Prob(X ) k X X ∈Σk ≤ X X ∈Σ Prob(X ) · 1 + log = H(Σk ) + 2 = k · H(Σ) + 2 Also erwartete Kodierungslänge pro Zeichen ∈ [H(Σ); H(Σ) + 2/k] 19/21 Wiederholung Erweiterte Huffman-Kodierung Dynamische Huffman-Kodes Arithmetische Kodes Implementierung: Rechnen mit beliebiger Genauigkeit Problem: ui − ℓi wird immer kleiner, irgendwann abgerundet zu 0 bei endlicher Genauigkeit Lösungsidee: Skalierung auf wesentlichen Bereich • 1. Fall (S1 ): ui < 0,5: dann erstes Bit verzichtbar, skaliere [0; 0,5[ → [0; 1[ durch x 7→ 2x. • 2. Fall (S2 ): ℓi ≥ 0,5: dann erstes Bit auch verzichtbar, skaliere [0,5; 1[ → [0; 1[ durch x 7→ 2(x − 0,5). • 3. Fall (S3 ): ℓi ≥ 0,25 und ui < 0,75: dann skaliere [0,25; 0,75[ → [0; 1[ durch x 7→ 2(x − 0,25). Gib Skalierungen aus: S1 : sofort 0-Bit schreiben, S2 : sofort 1-Bit schreiben, S3 : komplizierter, sei i die Anzahl aufeinanderfolgender S3 -Skalierungen. Danach in oberer oder unterer Hälfte von [1/2 − 2−i ; 1/2 + 2−i ]. Schreibe 10i bzw. 01i . 20/21 Wiederholung Erweiterte Huffman-Kodierung Dynamische Huffman-Kodes Arithmetische Kodes Vergleich arithm. Kodierung ↔ Huffman-Kodierung Erwartete Kodierungslänge pro Zeichen: Huffman-Kodierung: ≤ H(Σ) + 1/k arithmetische Kodierung: ≤ H(Σ) + 2/k Aber: Huffman-Kodierung erfordert Baum der Größe |Σ|k . Vorteil: arithmetische Kodes ohne komplizierte Datenstruktur, kleiner Nachteil: kompliziertere Arithmetik Anwendung: z. B. Grafikformat JBIG 21/21