Zum Inhalt springen
Zurück zur Themenübersicht

Angewandte Informatik

Datenkompression: Verfahren und ihre Grenzen

Wie man Daten kleiner macht, und warum kein Verfahren jede Datei verkleinern kann.

Benötigte Grundlagen

Dieses Vorwissen brauchst du für das Kapitel. Schau kurz nach, wenn dir etwas davon nicht mehr präsent ist, sonst leg direkt los.

Einführung

Ein Text schrumpft beim Packen auf ein Drittel. Ein Foto auf ein Zwanzigstel. Eine bereits gepackte dagegen wird durch nochmaliges Packen sogar größer.

Das Letzte wirkt wie ein Fehler des Programms und ist keiner. Es ist beweisbar unvermeidlich, und der Beweis dafür passt in wenige Zeilen.

In diesem Kapitel geht es um die Frage, woher die Einsparung eigentlich kommt, um zwei konkrete Verfahren und um die Grenze, an der jedes Verfahren haltmacht.

Das kannst du nach diesem Kapitel

  • verlustfreie und verlustbehaftete unterscheiden und begründet auswählen.

  • die Lauflängencodierung anwenden und ihre Grenzen erkennen.

  • die Huffman-Codierung aufbauen und begründen, warum sie eindeutig decodierbar ist (Vertiefung).

  • die Kompressionsrate berechnen.

  • beweisen, dass kein Verfahren alle verkleinern kann (Vertiefung).

Kurz aufgefrischt

Vorausgesetzt wird aus Datenkompression: verlustfrei und verlustbehaftet die Unterscheidung beider Arten und die Grundidee, Wiederholungen auszunutzen.

Neu sind hier die Verfahren selbst, ihre Begründung und ihre beweisbare Grenze.

Woher die Einsparung kommt

ist keine Zauberei. Sie beruht auf einer einzigen Beobachtung:

Reale sind nicht zufällig. Sie enthalten Wiederholungen, Muster und ungleich häufige Zeichen, kurz: Redundanz.

Beispiele:

  • In deutschem Text kommt das e\texttt{e} etwa hundertmal so oft vor wie das q\texttt{q}.
  • In einem Foto sind benachbarte Bildpunkte fast immer ähnlich.
  • In einer Tabelle wiederholen sich Werte.

Kompression ersetzt Redundanz durch eine kürzere Beschreibung. Wo keine Redundanz ist, gibt es nichts einzusparen, und genau darauf läuft die Grenze am Ende dieses Kapitels hinaus.

Verlustfrei oder verlustbehaftet

verlustfreiverlustbehaftet
Rückgewinnung für Bit exaktnur näherungsweise
Einsparungmäßig (Faktor 2 bis 4)groß (Faktor 10 bis 50)
VerfahrenZIP, PNG, FLACJPEG, MP3, MP4
geeignet fürTexte, Programme, TabellenBilder, Musik, Video

🔴 Die Wahl ist keine Geschmacksfrage. Bei einem Programm ändert ein einziges gekipptes Bit möglicherweise einen Befehl; die ist unbrauchbar. Bei einem Foto ist ein minimal verschobener Farbton für das Auge unsichtbar.

Die Leitfrage lautet: Ist eine Abweichung wahrnehmbar oder folgenlos? Bei Texten, Programmen und Messwerten nein. Dort ist nur verlustfrei zulässig. Bei Bild, Ton und Video ja, dort nutzt man aus, dass die menschliche Wahrnehmung ohnehin nicht alles erfasst.

Verlustbehaftete Verfahren lassen deshalb gezielt weg, was kaum wahrgenommen wird: Bei MP3 sind das Töne, die von lauteren überdeckt werden, bei JPEG feine Helligkeitsunterschiede, die das Auge nicht auflöst.

Lauflängencodierung

Das einfachste Verfahren. Statt jedes Zeichen einzeln zu speichern, notiert man Zeichen und Anzahl:

AAAAAAABBBCCCCCCCCCC   (20 Zeichen)
→  7A 3B 10C           (6 Zeichen)

Die ist hier

206≈3,3\frac{20}{6} \approx 3{,}3

Wo es gut funktioniert: Bei Bildern mit großen einfarbigen Flächen, etwa Symbolen, Zeichnungen oder gescannten Schwarz-Weiß-Seiten. Bei einem Faxbild bestehen ganze Zeilen aus Weiß.

🔴 Wo es scheitert: bei ohne Wiederholungen.

ABCDEFGH             (8 Zeichen)
→  1A 1B 1C 1D 1E 1F 1G 1H   (16 Zeichen)

Die „komprimierte" Fassung ist doppelt so groß. Das ist kein Einzelfall, sondern ein erster Hinweis auf die allgemeine Grenze am Ende des Kapitels.

Lauflängencodierung

OriginalAAAAAAABBBCCCCCCCCCClauflängencodiert7A3B10C20 Zeichen → 6 ZeichenDieselbe Folge, andersaufgeschrieben, nichts gehtverloren.

Oben die Folge, darunter ihre , und die Bilanz darunter ist gezählt, nicht behauptet: 20 Zeichen werden zu 6, die Rate ist 20:6≈3,320 : 6 \approx 3{,}3. Das Verfahren notiert nur, welches Zeichen wie oft hintereinander steht, mehr steckt nicht dahinter. Deshalb funktioniert es hervorragend bei Bildern mit großen einfarbigen Flächen, etwa Symbolen, Zeichnungen oder gescannten Schwarz-Weiß-Seiten, wo ganze Zeilen aus Weiß bestehen. 🔴 Und deshalb scheitert es ebenso zuverlässig, wo nichts wiederholt wird. Rechne selbst nach, was aus ABCDEFGH\texttt{ABCDEFGH} würde: acht Läufe der Länge eins, also 1A 1B 1C 1D 1E 1F 1G 1H\texttt{1A 1B 1C 1D 1E 1F 1G 1H}, doppelt so groß wie vorher. Das ist kein Ausrutscher des Verfahrens, sondern der erste Hinweis auf die Grenze, die weiter unten in diesem Kapitel bewiesen wird.

Vertiefung: Huffman-Codierung

Dieser Abschnitt gehört zum erhöhten Anforderungsniveau.

Die Lauflängencodierung nutzt nur Wiederholungen nebeneinander. Häufigkeiten nutzt sie gar nicht.

Die Idee der Huffman-Codierung ist deshalb eine andere:

Häufige Zeichen bekommen kurze , seltene lange.

Das ist derselbe Gedanke wie beim Morsealphabet, wo das häufige E\texttt{E} ein einzelner Punkt ist und das seltene Q\texttt{Q} vier Zeichen braucht.

Aufbau des Codes für den Text ABRACADABRA\texttt{ABRACADABRA} (11 Zeichen):

Häufigkeiten: A\texttt{A}: 5, B\texttt{B}: 2, R\texttt{R}: 2, C\texttt{C}: 1, D\texttt{D}: 1.

Schritt 1: Für jedes Zeichen einen mit seiner Häufigkeit anlegen. Schritt 2: Die beiden kleinsten zusammenfassen; der neue Knoten trägt die Summe. Schritt 3: Wiederholen, bis nur ein Knoten übrig ist. Schritt 4: Von der Wurzel aus jeder linken Kante eine 0 und jeder rechten eine 1 zuordnen; der Code eines Zeichens ist der Weg zu ihm.

                (11)
              /      \
          A(5)       (6)
                    /    \
                 (2)      (4)
                /   \    /   \
             C(1)  D(1) B(2) R(2)

Daraus:

ZeichenHäufigkeitCodeLänge
A501
C11003
D11013
B21103
R21113

Gesamtlänge: 5⋅1+1⋅3+1⋅3+2⋅3+2⋅3=235 \cdot 1 + 1 \cdot 3 + 1 \cdot 3 + 2 \cdot 3 + 2 \cdot 3 = 23 .

Zum Vergleich: Mit fester Länge bräuchte man bei fünf verschiedenen Zeichen 3 Bit je Zeichen, also 11⋅3=3311 \cdot 3 = 33 Bit. Die Einsparung beträgt rund 30 %.

Warum das eindeutig decodierbar ist. Die Codes haben verschiedene Längen, und trotzdem braucht man keine Trennzeichen. Der Grund ist die Baumkonstruktion: Alle Zeichen sitzen in den Blättern, nie in inneren Knoten. Deshalb ist kein Code der Anfang eines anderen; man nennt das präfixfrei.

Beim Decodieren läuft man vom Wurzelknoten aus die Bits entlang und gibt ein Zeichen aus, sobald man ein Blatt erreicht. Dann beginnt man wieder an der Wurzel. Eine Verwechslung ist ausgeschlossen.

Prüfe es an 0110\texttt{0110}: Die 0 führt sofort zum Blatt A\texttt{A}. Zurück zur Wurzel, dann 1→1→01 \to 1 \to 0 führt zu B\texttt{B}. Also AB\texttt{AB}, und eine andere Lesart gibt es nicht.

Huffman-Baum für ABRACADABRA

0101010111A 5624C 1D 1B 2R 2

An jeder Kante steht das , das sie beisteuert: links 0, rechts 1. Der eines Zeichens ist damit einfach der Weg von der Wurzel zu ihm, lies ihn ab: A=0\texttt{A} = 0, C=100\texttt{C} = 100, D=101\texttt{D} = 101, B=110\texttt{B} = 110, R=111\texttt{R} = 111. Der häufigste Buchstabe hängt direkt an der Wurzel und braucht ein Bit, die seltensten hängen ganz unten und brauchen drei; das ist derselbe Gedanke wie beim Morsealphabet. Rechne nach: 5⋅1+1⋅3+1⋅3+2⋅3+2⋅3=235 \cdot 1 + 1 \cdot 3 + 1 \cdot 3 + 2 \cdot 3 + 2 \cdot 3 = 23 Bit gegenüber 11⋅3=3311 \cdot 3 = 33 mit fester Länge, also rund 30 % gespart. 🔴 Und jetzt der Punkt, der leicht übersehen wird: Warum braucht man trotz verschiedener Längen keine Trennzeichen? Weil alle Zeichen in Blättern sitzen und keines in einem inneren . Deshalb ist kein Code der Anfang eines anderen. Prüfe es an 0110\texttt{0110}: Die 0 führt sofort ins Blatt A\texttt{A}, dann führt 1→1→01 \to 1 \to 0 zu B\texttt{B}. Also AB\texttt{AB}, und eine andere Lesart gibt es nicht.

Vertiefung: Warum kein Verfahren alle Dateien verkleinert

Dieser Abschnitt gehört zum erhöhten Anforderungsniveau.

Nun zu der Beobachtung aus der Einleitung. Man könnte sich ein Verfahren wünschen, das jede verkleinert. Ein solches kann es nicht geben, und der Beweis ist elementar.

Annahme: Ein verlustfreies Verfahren verkleinere jede Datei um mindestens ein .

Schritt 1: Betrachte alle Dateien der Länge nn Bit. Davon gibt es 2n2^n.

Schritt 2: Nach Annahme wird jede auf höchstens n−1n-1 Bit abgebildet. Dateien mit höchstens n−1n-1 Bit gibt es aber nur

2n−1+2n−2+…+21+20=2n−12^{n-1} + 2^{n-2} + \ldots + 2^1 + 2^0 = 2^n - 1

Schritt 3: Es sollen also 2n2^n Dateien auf 2n−12^n - 1 mögliche Ergebnisse abgebildet werden. Nach dem Schubfachprinzip müssen zwei verschiedene Dateien dasselbe Ergebnis liefern.

Schritt 4: Dann kann das Entpacken nicht mehr entscheiden, welche der beiden gemeint war. Das Verfahren ist nicht verlustfrei.

Widerspruch. Also verkleinert jedes verlustfreie Verfahren manche Dateien und vergrößert zwangsläufig andere.

🔴 Das ist keine technische Unzulänglichkeit, sondern eine Folge des Abzählens, und du erkennst dasselbe Argument wieder, das bei den Kollisionen der Streuspeicherung und beim Nachweis nichtregulärer Sprachen auftrat.

Was daraus folgt: funktionieren, weil reale eben nicht zufällig sind. Sie sind auf Texte, Bilder und Programme zugeschnitten und verkleinern genau diese zuverlässig. Eine bereits gepackte Datei enthält kaum noch Redundanz; ein zweiter Durchgang bringt nichts und fügt nur Verwaltungsdaten hinzu. Deshalb wird sie größer.

Die Abzählung hinter dem Beweis

LängenDateienmit n BitErgebnisse mit≤ n−1 Bit1212433878256255Immer genau ein Ergebnis zu wenig,ganz gleich, wie groß n ist.

Die Tabelle macht den Widerspruchsbeweis abzählbar. Angenommen, ein verlustfreies Verfahren verkleinerte jede um mindestens ein . Dann müssten die 2n2^n Dateien der Länge nn alle auf Dateien mit höchstens n−1n-1 Bit abgebildet werden, und davon gibt es nur 2n−1+…+2+1=2n−12^{n-1} + \ldots + 2 + 1 = 2^n - 1. Lies die dritte Zeile: 8 Dateien, aber nur 7 mögliche Ergebnisse. Nach dem Schubfachprinzip müssen also zwei verschiedene Dateien dasselbe Ergebnis liefern, und dann kann das Entpacken nicht mehr entscheiden, welche gemeint war. Das Verfahren wäre nicht verlustfrei: Widerspruch. 🔴 Also verkleinert jedes verlustfreie Verfahren manche Dateien und vergrößert zwangsläufig andere. Das ist keine technische Unzulänglichkeit, sondern eine Folge des Abzählens, und es ist dasselbe Argument, das bei den Kollisionen der Streuspeicherung und beim Nachweis nichtregulärer Sprachen auftrat. Dass trotzdem funktionieren, liegt allein daran, dass reale eben nicht zufällig sind.

Die Kompressionsrate

Rate=urspru¨ngliche Gro¨ßekomprimierte Gro¨ße\text{Rate} = \frac{\text{ursprüngliche Größe}}{\text{komprimierte Größe}}

Eine Rate von 4 bedeutet, dass die auf ein Viertel geschrumpft ist. Manchmal gibt man stattdessen die Ersparnis in Prozent an; bei Rate 4 sind das 75 %.

Bei verlustbehafteten Verfahren ist die Rate einstellbar: Man wählt zwischen Größe und Qualität. Ein JPEG mit hoher Rate zeigt sichtbare Blockmuster, eines mit niedriger ist kaum von der Vorlage zu unterscheiden.

Dasselbe Foto, drei Größen

Vorlage4.000.000 BPNG1.600.000 BJPEG200.000 BRate = ursprüngliche Größegeteilt durch komprimierteGröße.

Die Balkenlängen folgen einem einzigen Faktor, sind also wirklich vergleichbar. Rechne beide Raten nach: 4 000 000:1 600 000=2,54\,000\,000 : 1\,600\,000 = 2{,}5 für das verlustfreie PNG und 4 000 000:200 000=204\,000\,000 : 200\,000 = 20 für das verlustbehaftete JPEG. In Prozent gesprochen: 60 % gespart gegenüber 95 %. 🔴 Der Unterschied im Bild ist der Unterschied zwischen den beiden Sorten Verfahren, und er ist keine Geschmacksfrage. Das PNG lässt sich für Bit in die Vorlage zurückverwandeln, das JPEG nur näherungsweise. Es hat gezielt weggelassen, was das Auge ohnehin kaum auflöst. Bei einem Foto ist das folgenlos, bei einem Programm nicht: Dort kann ein einziges gekipptes Bit einen Befehl verändern und die unbrauchbar machen. Die Leitfrage lautet deshalb: Ist eine Abweichung wahrnehmbar oder folgenlos? Bei verlustbehafteten Verfahren ist die Rate zudem einstellbar, man wählt zwischen Größe und Qualität.

Lauflängencodierung und ihre Grenze

Codiere WWWWWWBBWWWWWWWWWB\texttt{WWWWWWBBWWWWWWWWWB} und berechne die Rate. Untersuche danach WBWBWBWB\texttt{WBWBWBWB}.

  1. 1

    Läufe abzählen: sechs W\texttt{W}, zwei B\texttt{B}, neun W\texttt{W}, ein B\texttt{B}. Zusammen 18 Zeichen.

  2. 2

    : 6W 2B 9W 1B\texttt{6W 2B 9W 1B}. Das sind acht Zeichen, wenn man jede Zahl und jeden Buchstaben zählt.

  3. 3

    Rate: 18:8=2,2518 : 8 = 2{,}25, also eine Ersparnis von rund 56 %.

  4. 4

    Nun WBWBWBWB\texttt{WBWBWBWB}: Jeder Lauf hat die Länge 1. Codiert ergibt das 1W 1B 1W 1B 1W 1B 1W 1B\texttt{1W 1B 1W 1B 1W 1B 1W 1B}, also 16 Zeichen statt 8.

  5. 5

    Rate: 8:16=0,58 : 16 = 0{,}5. Die ist doppelt so groß geworden.

  6. 6

    Die Lehre daraus: Ein Kompressionsverfahren ist immer auf eine bestimmte Art von Redundanz zugeschnitten. Die Lauflängencodierung nutzt Wiederholungen nebeneinander; wo es keine gibt, hilft sie nicht, sondern schadet. Praktische prüfen deshalb, ob die Codierung überhaupt kürzer wird, und speichern andernfalls unverändert.

6W 2B 9W 1B\texttt{6W 2B 9W 1B} mit Rate 2,25. Bei WBWBWBWB\texttt{WBWBWBWB} verdoppelt sich die Größe, weil keine Läufe vorhanden sind.

Einen Huffman-Code aufbauen

Baue den Huffman-Code für einen Text mit den Häufigkeiten E\texttt{E}: 8, N\texttt{N}: 5, S\texttt{S}: 3, T\texttt{T}: 2 und berechne die Ersparnis gegenüber fester Codelänge.

  1. 1

    Schritt 1: Vier mit den Häufigkeiten 8, 5, 3, 2.

  2. 2

    Schritt 2: die beiden kleinsten zusammenfassen: T\texttt{T} (2) und S\texttt{S} (3) ergeben einen Knoten mit 5.

  3. 3

    Schritt 3: wieder die beiden kleinsten: der neue Knoten (5) und N\texttt{N} (5) ergeben 10.

  4. 4

    Schritt 4: E\texttt{E} (8) und der Knoten (10) ergeben die Wurzel mit 18.

  5. 5

    Baum und (links 0, rechts 1):

                  (18)
                 /     \
              E(8)      (10)
                       /    \
                     (5)     N(5)
                    /   \
                 T(2)   S(3)
    
    ZeichenHäufigkeitCodeLänge
    E801
    N5112
    T21003
    S31013
  6. 6

    Huffman-Gesamtlänge: 8⋅1+5⋅2+2⋅3+3⋅3=8+10+6+9=338 \cdot 1 + 5 \cdot 2 + 2 \cdot 3 + 3 \cdot 3 = 8 + 10 + 6 + 9 = 33 Bit.

  7. 7

    Feste Länge: Bei vier Zeichen genügen 2 Bit je Zeichen, bei 18 Zeichen also 3636 Bit. Ersparnis: 3 Bit, rund 8 %.

  8. 8

    Warum hier so wenig? Die Häufigkeiten liegen nah beieinander. Huffman lohnt sich umso mehr, je ungleicher sie sind. Bei ABRACADABRA\texttt{ABRACADABRA} mit dem sehr häufigen A\texttt{A} waren es rund 30 %, und bei natürlichem Text mit seinem stark ungleichen Buchstabenvorkommen entsprechend viel.

33 statt 36 . Die Ersparnis wächst mit der Ungleichheit der Häufigkeiten.

Typischer Fehler

„Wenn ich eine ZIP-Datei noch einmal packe, wird sie noch kleiner."

Sie wird sogar größer, und das ist kein Fehler des Programms.

lebt von Redundanz. Ein Packprogramm sucht Wiederholungen und Muster und ersetzt sie durch kürzere Beschreibungen. Nach diesem Durchgang ist genau das aufgebraucht: Die gepackte enthält kaum noch erkennbare Muster, sie sieht fast zufällig aus.

Der zweite Durchgang findet also nichts mehr zum Einsparen, fügt aber trotzdem seine eigenen Verwaltungsdaten hinzu, etwa den Dateinamen und die Prüfsumme. Unterm Strich wächst die Datei um einige .

Und das ist nicht nur eine Beobachtung, sondern beweisbar. Es gibt 2n2^n Dateien der Länge nn, aber nur 2n−12^n - 1 Dateien, die kürzer als nn sind. Ein Verfahren, das jede Datei verkürzte, müsste zwei verschiedene auf dasselbe Ergebnis abbilden, und dann könnte das Entpacken sie nicht mehr unterscheiden. Das ist dasselbe Schubfachprinzip, das die Kollisionen bei der Streuspeicherung erzwingt.

Was tatsächlich hilft, wenn eine Datei zu groß ist:

  • Ein Verfahren wählen, das zu den passt: PNG für Grafiken mit Flächen, JPEG für Fotos, FLAC oder MP3 für Musik.
  • Bei Bild, Ton und Video die verlustbehaftete Stufe nutzen und die Qualität bewusst absenken.
  • Bei vielen kleinen Dateien diese gemeinsam packen, weil sich dann Muster über Dateigrenzen hinweg nutzen lassen.

Übung 1

leicht

a) Was unterscheidet verlustfreie von verlustbehafteter ? b) Codiere AAABBBBCC\texttt{AAABBBBCC} mit Lauflängencodierung und gib die Rate an. c) Nenne je zwei Dateiformate für beide Kompressionsarten.

Tipp anzeigen

Zu b): Zähle die Zeichen vorher und nachher.

Lösung anzeigen

a) Verlustfrei stellt die für Bit exakt wieder her; die Einsparung ist mäßig, etwa Faktor 2 bis 4. Verlustbehaftet stellt sie nur näherungsweise wieder her, erreicht dafür aber Faktor 10 bis 50. Zulässig ist Letzteres nur, wo die Abweichung nicht wahrgenommen wird oder folgenlos bleibt.

b) AAABBBBCC\texttt{AAABBBBCC} hat 9 Zeichen. : 3A 4B 2C\texttt{3A 4B 2C}, also 6 Zeichen.

Rate: 9:6=1,59 : 6 = 1{,}5, das entspricht rund 33 % Ersparnis.

c) Verlustfrei: ZIP, PNG (auch FLAC). Verlustbehaftet: JPEG, MP3 (auch MP4).

Detaillierte Schritterklärung anzeigen

Hier wird jeder Schritt einzeln erklärt, vor allem, warum er gemacht wird.

Erklärungstiefe

✦ Empfohlen: Standard – Die normale Erklärungstiefe passt zum Einstieg.

  1. 1

    a) Verlustfrei und verlustbehaftet: Wiederherstellbarkeit und Größenordnung

    Verlustfrei stellt die Daten Bit für Bit exakt wieder her; die Einsparung ist mäßig, etwa Faktor 2 bis 4. Verlustbehaftet stellt sie nur näherungsweise wieder her, erreicht dafür Faktor 10 bis 50. Zulässig ist Letzteres nur, wo die Abweichung nicht wahrgenommen wird oder folgenlos bleibt.

  2. 2

    b) Lauflängencodierung anwenden und die Rate berechnen

    Die Lauflängencodierung ersetzt Wiederholungen durch Anzahl plus Zeichen. AAABBBBCC\texttt{AAABBBBCC} hat 9 Zeichen und wird zu 3A 4B 2C\texttt{3A 4B 2C}, also 6 Zeichen. Rate: 9:6=1,59 : 6 = 1{,}5, das entspricht rund 33 % Ersparnis.

    9:6=1,59 : 6 = 1{,}5

    Zwischenergebnis

    Rate 1,51{,}5, rund 33 % Ersparnis.

  3. 3

    c) Je zwei Dateiformate und woran man sie erkennt

    Verlustfrei: ZIP, PNG (auch FLAC). Verlustbehaftet: JPEG, MP3 (auch MP4). Die Zuordnung folgt dem Zweck: Was ausgewertet oder weiterverarbeitet wird, ist verlustfrei; was nur angesehen oder angehört wird, darf verlustbehaftet sein.

Übung 2

mittel

a) Berechne die : 2400 kB werden zu 300 kB. b) Warum ist verlustbehaftete Kompression für Programme unzulässig, für Fotos aber üblich? c) Bei welchen versagt die Lauflängencodierung? Gib ein Beispiel mit Rechnung. d) (Vertiefung) Baue den Huffman-Code für die Häufigkeiten A\texttt{A}: 10, B\texttt{B}: 3, C\texttt{C}: 2, D\texttt{D}: 1.

Tipp anzeigen

Zu d): Immer die beiden kleinsten zusammenfassen, auch neu entstandene .

Lösung anzeigen

a) Rate=2400:300=8\text{Rate} = 2400 : 300 = 8. Die ist auf ein Achtel geschrumpft, das entspricht 87,5 % Ersparnis.

b) Bei einem Programm besteht die Datei aus Befehlen. Ein einziges verändertes kann einen Befehl in einen anderen verwandeln oder eine Adresse verfälschen; das Programm stürzt ab oder verhält sich falsch. Es gibt keine „ungefähr richtigen" Befehle.

Bei einem Foto verteilt sich die auf Millionen Bildpunkte, und die menschliche Wahrnehmung erfasst ohnehin nicht jeden Farbunterschied. Eine minimale Abweichung im Farbton ist unsichtbar, spart aber sehr viel Platz. Verlustbehaftete Verfahren lassen deshalb gezielt weg, was das Auge nicht auflöst.

c) Bei Daten ohne benachbarte Wiederholungen, denn genau die nutzt das Verfahren aus.

Beispiel ABCDEFGH\texttt{ABCDEFGH} mit 8 Zeichen. : 1A 1B 1C 1D 1E 1F 1G 1H\texttt{1A 1B 1C 1D 1E 1F 1G 1H}, also 16 Zeichen.

Rate: 8:16=0,58 : 16 = 0{,}5. Die Daten haben sich verdoppelt. Praktische Packprogramme prüfen deshalb, ob die Codierung kürzer ausfällt, und speichern andernfalls unverändert.

d) Zusammenfassen: D\texttt{D} (1) und C\texttt{C} (2) → Knoten (3). Knoten (3) und B\texttt{B} (3) → Knoten (6). Knoten (6) und A\texttt{A} (10) → Wurzel (16).

              (16)
             /     \
         A(10)      (6)
                   /    \
                 (3)     B(3)
                /   \
             D(1)   C(2)
ZeichenHäufigkeitCodeLänge
A1001
B3112
D11003
C21013

Gesamtlänge: 10⋅1+3⋅2+1⋅3+2⋅3=10+6+3+6=2510 \cdot 1 + 3 \cdot 2 + 1 \cdot 3 + 2 \cdot 3 = 10 + 6 + 3 + 6 = 25 Bit.

Mit fester Länge bräuchte man bei vier Zeichen 2 Bit, also 16⋅2=3216 \cdot 2 = 32 Bit. Ersparnis rund 22 %.

Detaillierte Schritterklärung anzeigen

Hier wird jeder Schritt einzeln erklärt, vor allem, warum er gemacht wird.

Erklärungstiefe

✦ Empfohlen: Standard – Die normale Erklärungstiefe passt zum Einstieg.

  1. 1

    Teil a): Die Formel richtig herum anwenden

    Die Rate ist Original geteilt durch komprimiert. Umgekehrt gerechnet käme ein Wert unter 1 heraus, der eine Vergrößerung bedeuten würde.

    \frac{2400}{300} = 8

    Zwischenergebnis

    Rate 8, also 87,5 % gespart.

    Die Umrechnung in Prozent lautet 1−1Rate1 - \tfrac{1}{\text{Rate}}. Bei Rate 8 sind das 1−0,125=0,8751 - 0{,}125 = 0{,}875.

  2. 2

    Teil b): Nach der Folge einer Abweichung fragen

    Man vergleicht, was ein verändertes Bit jeweils anrichtet. Bei einem Befehl ist die Wirkung beliebig, bei einem Bildpunkt begrenzt und unsichtbar.

    Zwischenergebnis

    Programme nur verlustfrei, Fotos auch verlustbehaftet.

  3. 3

    Teil c): Den ungünstigsten Fall konstruieren

    Man sucht Daten, in denen jeder Lauf die Länge 1 hat. Dann steht vor jedem Zeichen eine überflüssige Anzahl.

    8 \to 16 ;\Rightarrow; \text{Rate } 0{,}5

    Zwischenergebnis

    Verdoppelung statt Einsparung.

    Das ist ein erster Hinweis auf die allgemeine Grenze: Jedes Verfahren ist auf eine bestimmte Art von Redundanz zugeschnitten und schadet, wo sie fehlt.

  4. 4

    Teil d): Immer die zwei kleinsten, auch neue Knoten

    Nach jedem Zusammenfassen entsteht ein neuer Knoten, der bei der nächsten Auswahl gleichberechtigt mitzählt. Genau das wird am häufigsten übersehen.

    1 + 2 = 3;\quad 3 + 3 = 6;\quad 6 + 10 = 16

    Zwischenergebnis

    Codes: A = 0, B = 11, D = 100, C = 101.

Übung 3

schwer

a) (Vertiefung) Beweise, dass kein verlustfreies Verfahren alle verkleinern kann. b) Was folgt daraus für die Frage, ob mehrfaches Packen etwas bringt? c) (Vertiefung) Warum ist ein Huffman-Code ohne Trennzeichen eindeutig lesbar? d) Ein Schüler will ein bereits als JPEG gespeichertes Foto zusätzlich als ZIP packen. Beurteile das.

Tipp anzeigen

Zu a): Wie viele Dateien der Länge nn gibt es, und wie viele kürzere?

Lösung anzeigen

a) Annahme: Ein verlustfreies Verfahren verkleinere jede Datei um mindestens ein .

Betrachte alle Dateien der Länge genau nn Bit; davon gibt es 2n2^n. Nach Annahme wird jede auf eine Datei mit höchstens n−1n-1 Bit abgebildet. Dateien mit höchstens n−1n-1 Bit gibt es aber nur

2n−1+2n−2+…+21+20=2n−12^{n-1} + 2^{n-2} + \ldots + 2^1 + 2^0 = 2^n - 1

Es sollen also 2n2^n verschiedene Dateien auf 2n−12^n - 1 mögliche Ergebnisse abgebildet werden. Nach dem Schubfachprinzip müssen mindestens zwei verschiedene Dateien dasselbe Ergebnis liefern. Dann kann das Entpacken nicht mehr entscheiden, welche gemeint war, und das Verfahren ist nicht verlustfrei.

Widerspruch. Also verkleinert jedes verlustfreie Verfahren manche Dateien und vergrößert zwangsläufig andere.

b) Dass es nichts bringt und in aller Regel schadet. Beim ersten Durchgang wird die vorhandene Redundanz aufgebraucht; das Ergebnis sieht weitgehend zufällig aus. Der zweite Durchgang findet nichts mehr zum Einsparen, fügt aber seine eigenen Verwaltungsdaten hinzu, etwa Dateiname und Prüfsumme. Die Datei wird also um einige größer.

Der Beweis aus a) erklärt, warum das grundsätzlich so ist und nicht an einem schlechten Programm liegt: Ein Verfahren kann nicht alles verkleinern, und gepackte gehören zu denen, bei denen nichts mehr zu holen ist.

c) Weil der präfixfrei ist: Kein Code ist der Anfang eines anderen.

Das folgt unmittelbar aus dem Aufbau des Baums. Alle Zeichen sitzen in Blättern, nie in inneren . Der Code eines Zeichens ist der Weg von der Wurzel zu seinem Blatt; wäre ein Code der Anfang eines anderen, müsste das erste Zeichen auf dem Weg zum zweiten liegen, also in einem inneren Knoten sitzen. Das kann nicht sein.

Beim Decodieren läuft man deshalb vom Wurzelknoten die Bits entlang, gibt ein Zeichen aus, sobald ein Blatt erreicht ist, und beginnt wieder an der Wurzel. An keiner Stelle entsteht eine Wahlmöglichkeit.

d) Es bringt praktisch nichts. JPEG ist bereits ein Kompressionsverfahren, und zwar ein verlustbehaftetes, das speziell auf Bilddaten zugeschnitten ist. Es hat die Redundanz des Fotos bereits ausgenutzt. Die entstandene Datei enthält kaum noch Muster, die ein allgemeines Verfahren wie ZIP finden könnte.

Das Ergebnis ist typischerweise eine ZIP-Datei, die geringfügig größer ist als das JPEG. Sinnvoll ist ZIP hier nur aus einem anderen Grund, nämlich um mehrere Dateien zu einem Paket zusammenzufassen oder um sie mit einem Kennwort zu schützen. Als Mittel zur Verkleinerung taugt es an dieser Stelle nicht.

Wollte der Schüler das Foto wirklich kleiner bekommen, müsste er es mit stärkerer JPEG-Kompression neu speichern und dafür Qualität aufgeben.

Detaillierte Schritterklärung anzeigen

Hier wird jeder Schritt einzeln erklärt, vor allem, warum er gemacht wird.

Erklärungstiefe

✦ Empfohlen: Standard – Die normale Erklärungstiefe passt zum Einstieg.

  1. 1

    a) (Vertiefung) Die beiden Mengen abzählen

    Annahme: Ein verlustfreies Verfahren verkleinere jede Datei um mindestens ein Bit. Betrachte alle Dateien der Länge genau nn Bit, davon gibt es 2n2^n. Nach Annahme wird jede auf eine Datei mit höchstens n−1n-1 Bit abgebildet. Davon gibt es aber nur 2n−1+2n−2+…+20=2n−12^{n-1} + 2^{n-2} + \ldots + 2^0 = 2^n - 1.

    2n−1+2n−2+…+20=2n−12^{n-1} + 2^{n-2} + \ldots + 2^0 = 2^n - 1

  2. 2

    a) (Vertiefung) Das Schubfachprinzip liefert den Widerspruch

    Es sollen also 2n2^n verschiedene Dateien auf 2n−12^n - 1 mögliche Ergebnisse abgebildet werden. Nach dem Schubfachprinzip müssen mindestens zwei verschiedene Dateien dasselbe Ergebnis liefern. Dann kann das Entpacken nicht mehr entscheiden, welche gemeint war, das Verfahren ist nicht verlustfrei. Widerspruch.

  3. 3

    b) Was daraus für mehrfaches Packen folgt

    Dass es nichts bringt und in aller Regel schadet. Beim ersten Durchgang wird die vorhandene Redundanz aufgebraucht; das Ergebnis sieht weitgehend zufällig aus. Der zweite Durchgang findet nichts mehr zum Einsparen, fügt aber seine eigenen Verwaltungsdaten hinzu, die Datei wird also um einige Bytes größer.

  4. 4

    c) (Vertiefung) Warum ein Huffman-Code ohne Trennzeichen eindeutig lesbar ist

    Weil der Code präfixfrei ist: Kein Code ist der Anfang eines anderen. Das folgt unmittelbar aus dem Aufbau des Baums, alle Zeichen sitzen in Blättern, nie in inneren Knoten. Wäre ein Code der Anfang eines anderen, müsste das erste Zeichen auf dem Weg zum zweiten liegen, also in einem inneren Knoten sitzen. Das kann nicht sein.

  5. 5

    d) JPEG zusätzlich als ZIP packen: warum es nichts bringt

    Es bringt praktisch nichts. JPEG ist bereits ein Kompressionsverfahren, und zwar ein verlustbehaftetes, das speziell auf Bilddaten zugeschnitten ist. Es hat die Redundanz des Fotos bereits ausgenutzt; die entstandene Datei enthält kaum noch Muster, die ein allgemeines Verfahren wie ZIP finden könnte. Das Ergebnis ist typischerweise eine ZIP-Datei, die geringfügig größer ist.

Zusammenfassung

beruht darauf, dass reale nicht zufällig sind, sondern Wiederholungen, Muster und ungleiche Häufigkeiten enthalten; sie ersetzt diese Redundanz durch eine kürzere Beschreibung. Verlustfreie Verfahren stellen die Daten für Bit wieder her und sind bei Texten, Programmen und Messwerten die einzig zulässige Wahl, während verlustbehaftete Verfahren bei Bild, Ton und Video ausnutzen, dass die menschliche Wahrnehmung ohnehin nicht alles erfasst. Die Lauflängencodierung speichert Zeichen und Anzahl und wirkt dort, wo gleiche Werte nebeneinanderstehen; fehlen solche Läufe, vergrößert sie die Daten sogar. Die Huffman-Codierung nutzt stattdessen die Häufigkeiten aus und gibt häufigen Zeichen kurze ; weil alle Zeichen in Blättern des Baums sitzen, ist kein Code der Anfang eines anderen, und der Text bleibt ohne Trennzeichen eindeutig lesbar. Die Grenze aller Verfahren lässt sich abzählen: Es gibt 2n2^n der Länge nn, aber nur 2n−12^n - 1 kürzere, weshalb kein verlustfreies Verfahren alle Dateien verkleinern kann und mehrfaches Packen nichts bringt.