310 Algorithmen und Datenstrukturen 12 Greedy-Algorithmen • weitere Optimierungsstrategie, verwandt mit dynamischem Programmieren • Idee: wann immer eine Auswahl zu treffen ist wird die lokal optimale gewählt • In manchen Fällen führt dies auch zu einer global optimalen Lösung. 12 Greedy-Algorithmen TU Bergakademie Freiberg, WS 2005/06 311 Algorithmen und Datenstrukturen 12.1 Aktivitäten-Auswahl • n zeitlich begrenzte Aktivitäten S = {a1 , a2 , . . . , an } gegeben • Jede Aktivität ai benötigt über den Zeitraum [si , fi ), 0 ≤ si < fi < ∞, (Start- bzw. Endzeit) exklusiven Zugriff auf eine begrenzte Ressource. • Beispiele: Hörsaaleinteilung, Mietwagenverleih • Ziel: Auswahl einer möglichst großen Menge kompatibler (d.h. zeitlich nicht überlappender) Aktivitäten. Beispiel: (aufsteigend sortiert nach Endzeit) 12.1 Aktivitäten-Auswahl i 1 2 3 4 5 6 7 8 9 si 1 2 4 1 5 8 9 11 13 fi 3 5 7 8 9 10 11 14 16 TU Bergakademie Freiberg, WS 2005/06 312 Algorithmen und Datenstrukturen a5 a4 a2 a7 a1 0 1 2 a3 3 4 5 a9 a6 6 7 8 9 a8 10 11 12 13 14 15 16 Maximale kompatible Menge {a1 , a3 , a6 , a8 } nicht eindeutig: auch {a2 , a5 , a7 , a9 } 12.1 Aktivitäten-Auswahl TU Bergakademie Freiberg, WS 2005/06 313 Algorithmen und Datenstrukturen Optimale Substruktur Definiere Si,j = {ak ∈ S : fi ≤ sk < fk ≤ sj } = Aktivitäten, welche nach ai beginnen und vor aj enden . Aktivitäten in Si,j sind kompatibel mit allen Aktivitäten, die • bis fi enden oder • nicht vor sj beginnen. Gesamtaufgabe kann beschrieben werden mit Hilfe zweier fiktiver Aktivitäten a0 := [−∞, 0), an+1 := [∞, “∞ + 1”), womit S = S0,n+1 . 12.1 Aktivitäten-Auswahl TU Bergakademie Freiberg, WS 2005/06 314 Algorithmen und Datenstrukturen Aktivitäten seien nach aufsteigender Endzeit sortiert: f0 ≤ f1 ≤ f2 ≤ · · · ≤ fn < fn+1 . Es gilt Si,j = ∅ falls i ≥ j. Beweis: Aus ak ∈ Si,j folgt fi ≤ sk < fk ≤ sj < fj . Wegen i ≥ j gilt aber fi ≥ fj , ein Widerspruch. (12.1) Daher: betrachte nur Si,j mit 0 ≤ i < j ≤ n + 1. 12.1 Aktivitäten-Auswahl TU Bergakademie Freiberg, WS 2005/06 315 Algorithmen und Datenstrukturen Enthält eine Lösung zu Si,j das Element ak , so ergeben sich 2 Teilprobleme: • Si,k (Start nach Ende von ai , Ende vor Start von ak ) • Sk,j (Start nach Ende von ak , Ende vor Start von aj ) Lösung von Si,j gegeben durch Lösung von Si,k ∪ {ak } ∪ Lösung von Sk,j Da Si,k , Sk,j disjunkt und ak in keiner der beiden Mengen enthalten gilt |Lösung von S| = |Lösung von Si,k | + 1 + |Lösung von Sk,j |. 12.1 Aktivitäten-Auswahl TU Bergakademie Freiberg, WS 2005/06 316 Algorithmen und Datenstrukturen Enthält eine optimale Lösung zu Si,j das Element ak , so sind die darin vorkommenden Lösungen zu Si,k und Sk,j ebenfalls optimal. (Üblicher cut-and-paste Beweis) Wir nehmen an: Ai,j sei optimale Lösung von Si,j , d.h. Ai,j = Ai,k ∪ {ak } ∪ Ak,j . Dabei sei Si,j 6= ∅ und ak sei bekannt. 12.1 Aktivitäten-Auswahl TU Bergakademie Freiberg, WS 2005/06 317 Algorithmen und Datenstrukturen Rekursive Lösung der Aktivitätenauswahl Sei c[i, j] := Größe einer maximalen Menge kompatibler Aktivitäten in Si,j Wegen (12.1) folgt c[i, j] = 0 falls i ≥ j. Ist Si,j 6= ∅ und liegt ak ∈ Si,j , so gilt ( 0 c[i, j] = max{c[i, k] + 1 + c[k, j] : i < k < j, ak ∈ Si,j } falls Si,j = ∅, falls Si,j 6= ∅. Beachte: • Wegen Si,j = {ak ∈ S : fi ≤ sk < fk ≤ sj } folgt ak 6= ai , aj . • ak ∈ Si,j muss zusätzlich gefordert werden, da dies nicht bereits aus i < k < j folgt. 12.1 Aktivitäten-Auswahl TU Bergakademie Freiberg, WS 2005/06 318 Algorithmen und Datenstrukturen An dieser Stelle könnte man weiterverfahren mit einer Lösung durch dynamisches Programmieren. Es geht aber auch einfacher. Satz 12.1 Sei Si,j 6= ∅ sowie am diejenige Aktivität in Si,j mit der frühesten Endzeit: fm = min{fk : ak ∈ Si,j }. Dann gilt (a) am liegt auch in einer maximalen kompatiblen Teilmenge von Si,j . (b) Si,m = ∅, d.h. nach Auswahl von am verbleibt lediglich Sm,j als einziges nichtleeres Teilproblem. Beweis: (b) Aus ak ∈ Si,m folgt fi ≤ sk < fk ≤ sm < fm , insbesondere fk < fm . Damit läge ak auch in Si,j , besäße aber eine frühere Endzeit als fm , ein Widerspruch. Es ist also Si,m = ∅. 12.1 Aktivitäten-Auswahl TU Bergakademie Freiberg, WS 2005/06 319 Algorithmen und Datenstrukturen (a) Sei Ai,j eine maximale kompatible Teilmenge von Si,j . Die Elemente von Ai,j seien nach aufsteigender Endzeit sortiert. Sei ak die erste Aktivität in dieser Reihenfolge. Ist ak = am , so ist die Behauptung bewiesen. Andernfalls setze A0i,j := Ai,j \ {ak } ∪ {am } (ersetze ak durch am ). Behauptung: die Aktivitäten in A0i,j sind kompatibel. Die Aktivitäten in Ai,j sind kompatibel, ak besitzt hiervon die früheste Endzeit, ferner gilt fm ≤ fk . Damit besitzt am keine Konflikte mit Elementen aus A0i,j . Da |A0i,j | = |Ai, j| und Ai,j eine maximale kompatible Menge ist, ist dies auch A0i,j . . 12.1 Aktivitäten-Auswahl TU Bergakademie Freiberg, WS 2005/06 320 Algorithmen und Datenstrukturen Starke Vereinfachung: # Teilprobleme einer optimalen Lösung # Auswahlmöglichkeiten ohne Satz 12.1 mit Satz 12.1 2 1 j-i-1 1 Nun ist eine top-down Strategie möglich: um Si,j zu lösen • Auswahl von am ∈ Si,j mit frühester Endzeit, die Greedy-Auswahl, • danach Lösung von Sm,j . 12.1 Aktivitäten-Auswahl TU Bergakademie Freiberg, WS 2005/06 321 Algorithmen und Datenstrukturen Reihenfolge der Teilprobleme: • Starte mit S0,n+1 . • Wird am1 zuerst ausgewählt, fahre fort mit Teilproblem Sm1 ,n+1 . • Wird am2 als nächstes ausgewählt, fahre fort mit Teilproblem Sm2 ,n+1 . • Und so fort. Jedes Teilproblem Smi ,n+1 besteht aus den Aktivitäten mit den spätesten Endzeiten. Die Teilprobleme besitzen also wachsende Endzeiten. Es genügt deshalb, jede Aktivität nur einmal, in Reihenfolge wachsender Endzeit, zu betrachten. 12.1 Aktivitäten-Auswahl TU Bergakademie Freiberg, WS 2005/06 322 Algorithmen und Datenstrukturen Einfacher rekursiver Algorithmus: Aktivitäten nach aufsteigender Endzeit sortiert angenommen. (Andernfalls zusätzlich mit Zeitaufwand O(n log n) sortieren.) Liefert eine optimale Lösung von Si,n+1 . R EC -ACTIVITY-S ELECTOR(s, f, i, n) 1 m←i+1 2 while m ≤ n und sm < fi Bestimme erste Aktivität in Si,n+1 3 do m ← m + 1 4 if m ≤ n 5 then return {am } ∪ R EC -ACTIVITY-S ELECTOR(s, f, m, n) 6 else return ∅ Erster Aufruf: R EC -ACTIVITY-S ELECTOR(s, f, 0, n). 12.1 Aktivitäten-Auswahl TU Bergakademie Freiberg, WS 2005/06 323 Algorithmen und Datenstrukturen Idee: Die while -Schleife prüft sukzessiv die Elemente ai+1 , ai+2 , . . . , an , bis eine (die erste) mit ai kompatible Aktivität am gefunden wird (dies erfordert sm ≥ fi . • Terminiert die Schleife durch Auffinden eines solchen am (m ≤ n), so wird rekursiv Sm+1,n gelöst und diese Lösung, mit am vorangestellt, zurückgegeben. • Wird keine kompatible Aktivität am gefunden, so wird die leere Menge zurückgegeben. Laufzeit: Θ(n), da jede Aktivität genau einmal geprüft wird. 12.1 Aktivitäten-Auswahl TU Bergakademie Freiberg, WS 2005/06 324 Algorithmen und Datenstrukturen Iterative Variante: G REEDY-ACTIVITY-S ELECTOR(s, f, n) 1 2 3 4 5 6 7 A ← {a1 } i←1 for m ← 2 to n do if sm ≥ fi then A ← A ∪ {am } i←m ai wurde als letztes hinzugetan return A Laufzeit: Θ(n). 12.1 Aktivitäten-Auswahl TU Bergakademie Freiberg, WS 2005/06 325 Algorithmen und Datenstrukturen Greedy-Strategie Jede Auswahl wird lokal optimal getroffen. Vorgehen bei Aktivitätenauswahl: 1. Bestimmung der optimalen Substruktur 2. Entwicklung einer rekursiven Lösung 3. Zeige: In jedem Stadium der Rekursion ist die Greedy-Auswahl eine der optimalen Möglichkeiten. D.h. man ist mit der Greedy-Auswahl immer auf der sicheren Seite. 4. Zeige: bis auf eine sind alle aus der Greedy-Auswahl sich ergebenden Teilprobleme leer. 5. Entwicklung eines rekursiven Greedy-Algorithmus 6. Umwandlung in einen iterativen Algorithmus. 12.1 Aktivitäten-Auswahl TU Bergakademie Freiberg, WS 2005/06 326 Algorithmen und Datenstrukturen Im Allgemeinen wird dieses Vorgehen verkürzt. Wir hatten gezeigt: treffen der Greedy-Auswahl führte dazu, dass in Si,j nur i variierte und j beim Wert n + 1 konstant blieb. Man hätte auch von vornherein einen Greedy-Algorithmus ansteuern können: • Setze Si := {ak ∈ S : sk ≥ fi }. • Zeige dann: die Greedy-Auswahl am – die am frühesten endende Aktivität in Si – kombiniert mit einer optimalen Lösung von Sm führt auf eine optimale Lösung von Si . 12.1 Aktivitäten-Auswahl TU Bergakademie Freiberg, WS 2005/06 327 Algorithmen und Datenstrukturen Typisches verkürztes Vorgehen: 1. Formulierung der Optimierungsaufgabe als eine, zu deren Lösung eine Auswahl getroffen wird, wonach ein Teilproblem zu lösen bleibt. 2. Zeige: es gibt stets eine optimale Lösung, bei welcher die GreedyAuswahl getroffen wird. Dies stellt sicher, dass die Greedy-Auswahl zu einer optimalen Lösung führt. 3. Zeige: Greedy-Auswahl verbunden mit optimaler Lösung des verbleibenden Teilproblems führt auf global optimale Lösung. Es gibt kein allgemeingültiges Kriterium, wann ein Greedy-Algorithmus optimal ist, jedoch zwei wesentliche Komponenten: • die Greedy-Auswahl-Eigenschaft sowie • optimale Substruktur. 12.1 Aktivitäten-Auswahl TU Bergakademie Freiberg, WS 2005/06 328 Algorithmen und Datenstrukturen Greedy-Auswahleigenschaft Durch lokal optimale Auswahlen (Greedy-Auswahl) kann eine global optimale Lösung konstruiert werden. Man vergleiche Dynamisches Programmieren: • Auswahl bei jedem Schritt • Auswahl setzt Kenntnis der optimalen Lösungen der Teilprobleme voraus; daher müssen diese zuerst gelöst werden. • Bottom-up Vorgehen. Greedy: • Auswahl bei jedem Schritt • Auswahl wird vor Lösung der Teilprobleme getroffen. • Top-down Vorgehen. 12.1 Aktivitäten-Auswahl TU Bergakademie Freiberg, WS 2005/06 329 Algorithmen und Datenstrukturen Optimale Substruktur Zeige, dass die Greedy-Auswahl verbunden mit der optimalen Lösung des verbleibenden Teilproblems zu einer global optimalen Lösung führt. 12.1 Aktivitäten-Auswahl TU Bergakademie Freiberg, WS 2005/06 330 Algorithmen und Datenstrukturen Beispiel: Unterschied Greedy vs. dynamisches Programmieren 0-1 Knappsack-Problem • n Objekte • Objekt i besitzt Wert vi EUR und Gewicht wi kg • Ziel: Zusammenstellen einer möglichst wertvollen Ansammlung von Objekten mit Gesamtgewicht ≤ W • Objekte können nur als Ganze ausgewählt werden (nicht anteilig) Anteiliges Knappsack-Problem Wie 0-1 Knappsack-Problem, aber hier können Objekte auch anteilig ausgewählt werden. 12.1 Aktivitäten-Auswahl TU Bergakademie Freiberg, WS 2005/06 331 Algorithmen und Datenstrukturen • Beide besitzen die optimale Substruktureigenschaft • Das anteilige Knappsack-Problem besitzt die Greedy-Auswahleigenschaft, das 0-1-Knappsack-Problem hingegen nicht. Zur Lösung des anteiligen Problems: Objekte zunächst nach Quotient vi /wi absteigend sortieren. F RACTIONAL -K NAPPSACK(v, w, W ) load ← 0 while load < W und i ≤ n do if wi ≤ W − load then Objekt i vollständig auswählen else Anteil (W − load )/wi von Objekt i auswählen load um Gewicht der Auswahl erhöhen i←i+1 Laufzeit: O(n log n) zum Sortieren, danach O(n). 12.1 Aktivitäten-Auswahl TU Bergakademie Freiberg, WS 2005/06 332 Algorithmen und Datenstrukturen Die Greedy-Strategie funktioniert nicht für das 0-1 Knappsack Problem. Beispiel: i 1 2 3 vi 60 100 120 wi 10 20 30 vi /wi 6 5 4 W = 50. Greedy-Lösung • Wählt zuerst Objekt 1, danach Objekt 2. Wert = 160, Gewicht = 30. 20 kg ungenutzt. Optimale Lösung • Wähle Objekte 2 und 3. Wert = 220, Gewicht = 50. • Zulässiges Gewicht voll ausgenutzt. 12.1 Aktivitäten-Auswahl TU Bergakademie Freiberg, WS 2005/06 333 Algorithmen und Datenstrukturen 12.2 Huffman-Codes • weit verbreitete, sehr effektive Technik zur Datenkompression • Je nach Daten Ersparnis von 20-90% • Betrachte Daten als Folge von Zeichen • Greedy-Algorithmus von Huffman: weist anhand einer Häufigkeitstabelle jedem Zeichen eine optimale Binärkodierung zu. • Beispiel: Kompression einer Datei aus 100.000 Zeichen aus dem Alphabet {a, b, c, d, e, f}. Die Häufigkeit des Auftretens der einzelnen Zeichen sei gegeben durch folgende Tabelle: 12.2 Huffman-Codes TU Bergakademie Freiberg, WS 2005/06 334 Algorithmen und Datenstrukturen a b c d e f Häufigkeit (in Tausend) 45 13 12 16 9 5 Kodierung fester Länge 000 001 010 011 100 101 0 101 100 111 1101 1100 Kodierung variabler Länge Kodierung fester Länge: Für 6 Zeichen 3 Bits erforderlich, z.B. a = 000, b = 001,. . . ,f = 101. Die Speicherung Datei erfordert auf diese Weise 300.000 Bits. Kodierung variabler Länge: Verbesserung durch Vergabe von kurzen Codes an häufig auftretende Zeichen. Bei der in der Tabelle angegebenen Kodierung variabler Länge benötig man (45 · 1 + 13 · 3 + 12 · 3 + 16 · 3 + 9 · 4 + 5 · 4) · 1000 = 224.000 Bits, eine Ersparnis von ca. 25 %. Später: diese Kodierung ist optimal. 12.2 Huffman-Codes TU Bergakademie Freiberg, WS 2005/06 335 Algorithmen und Datenstrukturen 12.2.1 Präfix-Kodierungen Betrachte ausschließlich sog. Präfix-Kodierungen, bei denen kein Zeichencode mit der Anfangsfolge (Präfix) eines anderen Zeichencodes zusammenfällt.a • Kodierung der Datei einfach: Aneinanderreihen der Zeichencodes. Mit der variablen Kodierung wird etwa die Datei abc kodiert als 0·101·100 = 0101100. • Dekodierung für Präfix-Codes ebenfalls einfach: Bits lesen bis ein Zeichen vollständig, dann Ersetzen durch kodiertes Zeichen. Beispiel: 00101101 → 0 · 0 · 101 · 1101 → aabe. a Man kann zeigen: die optimale durch Zeichenkodierung erreichbare Kompression kann mit einem Präfix-Code erreicht werden. Daher stellt dies keine Einschränkung dar. 12.2 Huffman-Codes TU Bergakademie Freiberg, WS 2005/06 336 Algorithmen und Datenstrukturen Hilfreiche Darstellung des Präfix-Kodierschemas zum Dekodieren • Binärbaum mit den kodierten Zeichen als Blätter • Bitfolge der Zeichenkodierung entspricht Weg von Wurzel zum Blatt mit kodiertem Zeichen: bei 0: linker Sohn, bei 1: rechter Sohn. • Keine binären Suchbäume (innere Knoten tragen keine Schlüssel, Zeichen nicht sortiert) • Optimale Kodierungen besitzen einen vollständigen Binärbaum (jeder Knoten, der kein Blatt ist, besitzt 2 Söhne). • Ist T die Binärbaumdarstellung des Kodierschemas und bezeichnen C das Alphabet, f (c) die Häufigkeit von Zeichen c ∈ C in der Datei sowie dT (c) die Tiefe des zu c gehörenden Blattes, so ist die erforderliche Anzahl Bits B(T ) zur Kodierung der Datei gegeben durch X B(T ) = f (c)dT (c). c∈C 12.2 Huffman-Codes TU Bergakademie Freiberg, WS 2005/06 337 Algorithmen und Datenstrukturen 100 0 55 a:45 100 0 0 1 86 0 1 25 14 1 58 0 28 14 1 0 c:12 30 1 0 1 b:13 14 d:16 0 1 0 1 0 1 0 a:45 b:13 c:12 d:16 e:9 f:5 f:5 (a) 1 e:9 (b) Bäume zu den Kodierungsschemata fester (a) und variabler (b) Länge im Beispiel. Die Blätter sind mit den Zeichen und deren Häufigkeiten bezeichnet. Innere Knoten sind mit der Summe der Häufigkeiten in den Blättern ihrer Teilbäume bezeichnet. 12.2 Huffman-Codes TU Bergakademie Freiberg, WS 2005/06 338 Algorithmen und Datenstrukturen 12.2.2 Konstruktion von Huffman-Codes • Greedy-Algorithmus von David A. Huffman zur Konstruktion eines optimalen Präfix-Codes • Korrektheitsnachweis beruht auf Greedy-Auswahleigenschaft und optimaler Substruktureigenschaft. • Wir betrachten zuerst den Pseudocode ◦ C: Menge von n Zeichen, Zeichen c ∈ C besitzt Häufigkeit f (c) ◦ Binärbaumdarstellung der optimalen Kodierung wird mit Bottom-up Vorgehen aufgebaut. ◦ Beginnt mit |C| Blätter und führt |C| − 1 Verknüpfungsoperationen durch. Ergebnis: neuer Knoten, Häufigkeit ist Summe der Häufigkeiten der Söhne. 12.2 Huffman-Codes TU Bergakademie Freiberg, WS 2005/06 Algorithmen und Datenstrukturen 339 H UFFMAN(C) 1 2 3 4 5 6 7 8 9 n ← |C| Q←C for i ← 1 to n − 1 do neuen Knoten z allokieren left[z] ← x ← E XTRACT-M IN(Q) right[z] ← y ← E XTRACT-M IN(Q) f (z) ← f (x) + f (y) I NSERT(Q, z) return E XTRACT-M IN(Q) Beachte: Im Pseudocode wird eine sog. Min-Priority-Queue verwendet, eine Datenstruktur, welche die Operationen I NSERT, M INIMUM, E XTRACTM IN und D ECREASE -K EY unterstützt. Diese kann durch einen Heap implementiert werden. 12.2 Huffman-Codes TU Bergakademie Freiberg, WS 2005/06 340 Algorithmen und Datenstrukturen (a) f:5 e:9 d:16 c:12 b:13 a:45 (b) c:12 14 b:13 0 14 0 f:5 25 d:16 1 e:9 a:45 (d) e:9 25 30 0 1 0 1 c:12 b:13 c:12 b:13 a:45 1 f:5 (c) d:16 0 1 14 0 f:5 a:45 d:16 1 e:9 Die Schritte des Huffman-Algorithmus für das Kodierschema variabler Länge. In jeder Phase wird von links nach rechts der Inhalt der Min-Priority-Queue nach aufsteigender Häufigkeit sortiert dargestellt. In jedem Schritt werden die zwei Bäume mit den niedrigsten Häufigkeiten vereinigt. 12.2 Huffman-Codes TU Bergakademie Freiberg, WS 2005/06 341 Algorithmen und Datenstrukturen (e) 55 a:45 0 (f) 1 25 0 c:12 100 0 30 0 1 b:13 14 d:16 f:5 55 a:45 1 0 1 1 e:9 0 1 25 0 c:12 30 1 0 1 b:13 14 d:16 0 f:5 12.2 Huffman-Codes 1 e:9 TU Bergakademie Freiberg, WS 2005/06 342 Algorithmen und Datenstrukturen Laufzeit des Huffman-Algorithmus: • Implementierung von Q als Min-Heap. • Initialisierung in O(n) mit B UILD -M IN -H EAP. • for -Schleife (Zeile 3) wird n − 1 Mal ausgeführt, jede Heap-Operation benötigt O(log n), also benötigt die Schleife O(n log n). • Fazit: Huffman-Algorithmus angewandt auf Menge mit C Elementen besitzt Laufzeit O(n log n). 12.2 Huffman-Codes TU Bergakademie Freiberg, WS 2005/06 343 Algorithmen und Datenstrukturen 12.2.3 Korrektheit des Huffman-Algorithmus Korrektheitsbeweis beruht darauf, dass das die Aufgabe, eine optimale Präfix-Kodierung zu bestimmen, die Greedy-Auswahleigenschaft und die optimale Substruktureigenschaft besitzt. Zunächst die Greedy-Auswahleigenschaft: Lemma 12.2 Sei C ein Alphabet aus n Zeichen und seien x und y zwei Zeichen aus C mit minimaler Häufigkeit. Dann gibt es eine optimale PräfixKodierung für C, in welcher die Zeichenkodierungen von x und y die gleiche Anzahl Bits besitzen und sich nur im letzten Bit unterscheiden. Fazit: der Aufbau eines optimalen Baumes kann o.B.d.A. mit dem Verbinden zweier Zeichen minimaler Häufigkeit beginnen. Betrachtet man die Summe der Häufigkeiten zu verbindender Knoten als Kosten, so stellt diese Auswahl eine Greedy-Auswahl dar. 12.2 Huffman-Codes TU Bergakademie Freiberg, WS 2005/06 344 Algorithmen und Datenstrukturen Lemma 12.3 Sei C ein Alphabet aus n Zeichen, wobei Zeichen c ∈ C mit Häufigkeit f (c) auftritt. Seien x und y zwei Zeichen aus C mit minimaler Häufigkeit. Sei ferner C 0 das Alphabet, das durch Entfernen von x und y aus C und Hinzunahme eines neuen Zeichens z entsteht. Die Häufigkeiten in C 0 seien wie in C definiert zusammen mit f (z) := f (x) + f (y). Sei schliesslich T 0 ein beliebiger Baum, der eine optimale Präfix-Kodierung für C 0 repräsentiert. Dann repräsentiert der Baum T , der dadurch aus T 0 entsteht, dass das zu z gehörende Blatt ersetzt wird durch einen inneren Knoten mit Söhnen x und y, eine optimale Präfix-Kodierung für C. Damit ist die optimale Substruktureigenschaft ebenfalls nachgewiesen. Es folgt somit: Satz 12.4 Algorithmus H UFFMAN konstruiert eine optimale Präfix-Kodierung. 12.2 Huffman-Codes TU Bergakademie Freiberg, WS 2005/06