Huffman abspeichern
-
Hi!
Wie kann man am geeignetsten den Binärbaum(also das Alphabet) unterbringen, so das es am wenigsten speicher verschlingt.Also zum Beispiel bei "MISSISSIPPI" wird folgendes erstellt:
Alphabet:
I: 00
P: 010
M: 011
S: 1Kodiert:
M: 011
I: 00
S: 1
S: 1
I: 00
S: 1
S: 1
I: 00
P: 010
P: 010
I: 00Ich stehe z. Z. voll aufm Schlauch. Eine Idee wäre doch
I: 00
P: 010
M: 011
S: 1So zu Ordnen, das die Astlänge(sprich Anzahl von Nullen und Einsen) von oben nach unten ist. Die Binärfolgen von Zeichen mit gleicher Astlänge könnte man doch beliebig ausstauschen(natürlich müsste man dies auch beim Kodieren der Zeichen berücksichtigen) ?oder
So könnte man die Zeichen mit selber Astlänge nochmals dem ASCII-Codes nach Ordnen. Am besten so, das das erste Zeichen dann bei z. B. eine Binärlänge von 4 Bit bei 0000 beginnt, das zweite 0001, das dritte 0010, das vierte 0011 usw. bekommt.
Der Astlänge nach sortiert:
S: 1
I: 00
P: 010
M: 011P und M haben die selbe Astlänge, man kann hier bei P an beginnen zu zählen:
S: 1
I: 00
P: 000
M: 001Die große Frage ist, verlieren dann die Zeichen ihre Eindeutigkeit die beim Dekodieren wichtig ist?
Darf man das bei 000 beginnen zu Zählen nicht durchführen?
mfg olli
-
naja, P = 000 klappt ja schon mal nicht, weils dann nicht mehr präfixfrei ist. du wirst nicht drumrum kommen, die schlüsseltabelle unkomprimiert zu speichern, und zwar jeweils wortlänge und wort"inhalt" (also bei 010 z.b. 3 und 2)
-
Vertex schrieb:
So zu Ordnen, das die Astlänge(sprich Anzahl von Nullen und Einsen) von oben nach unten ist. Die Binärfolgen von Zeichen mit gleicher Astlänge könnte man doch beliebig ausstauschen(natürlich müsste man dies auch beim Kodieren der Zeichen berücksichtigen) ?oder
jo, kann man.
So könnte man die Zeichen mit selber Astlänge nochmals dem ASCII-Codes nach Ordnen. Am besten so, das das erste Zeichen dann bei z. B. eine Binärlänge von 4 Bit bei 0000 beginnt, das zweite 0001, das dritte 0010, das vierte 0011 usw. bekommt.
jo, mach das. ich bin zu dem gleichen ergebnis gekommen.
Der Astlänge nach sortiert:
S: 1
I: 00
P: 010
M: 011P und M haben die selbe Astlänge, man kann hier bei P an beginnen zu zählen:
S: 1
I: 00
P: 000
M: 001ich würde anders sortieren:
S: 1 I: 00 P: 000 M: 001
und da den code auch ändern darf, indem ich an alen codewörter die gleiche stelle invertiere, mache ich draus
S: 0 I: 10 P: 100 M: 101
und
S: 0 I: 10 M: 110 P: 111
nu ist der baum sortiert nach wirtlängen und innerhalb der wortlängen auch alphabetisch.
als darstellung reicht "S,I,MP" aber wichtiger finde ich die andere sache: es reicht, die wortlängen zu wissen. bei einer dicken datei, wo jedes zeichen mal vorkommt, brauchst nur noch die wortlängen abzuspeichern. die rehenfolge ist dann definiert. und die wortlängen kann man vermutlich auch nochmal gut packen. zum beispiel
0: 0000
1: 0001
2: 0010
...
14: 1110
15: 1111 00000000
16: 1111 00000001
17: 1111 00000010
ka, ob das sinn ergibt, so zu packen. wäre halt einfach.Die große Frage ist, verlieren dann die Zeichen ihre Eindeutigkeit die beim Dekodieren wichtig ist?
ich sehe kein problem. wenigstens nicht bei meinem code.
Darf man das bei 000 beginnen zu Zählen nicht durchführen?
P und M haben die selbe Astlänge, man kann hier bei P an beginnen zu zählen:
S: 1
I: 00
P: 000
M: 001wenn du den baum so sortiert hast, daß zuerst kurze wörter kommen und bei gleich langen wörtern die lexikographisch kleineren, und du dann mir die liste S,i,PM gibst, dann hab ich doch folgende garantien:
S ist ...
keine ahnung. kann 0 oder 1 sein.
ich nehm doch meinen code.S: 0
I: 10
M: 110
P: 111
und du schickst S,I,MPich erzeuge alle möglichen wörter der länge 1:
freie wörter: 0 1
S hat länge 1. die wörter 0 und 1 sind noch frei, ich nehme das kleinere. S: 0
freie wörter: 1
dann lese ich ein "," und gehe deswegen zur wortlänge 2. dazu verlängere ich jedes freie wort mit 0 und 1
freie wörter: 10 11
I weise ich das nächste freie wort zu. I: 01
freie wörter: 11
dann gehe ich zu wortlänge 3
freie wörter: 110 111
und weise M die 110 zu und weise P die 111 zu.
-
Hi!
Danke für die Antworten!volkard: Hmm wie Korbinian schon sagte, kann man leider doch nicht die Codes beliebig austauschen. (Auch wenn sie gleicher Länge sind, und nur einmal vorkommen)
Eben bei:
S: 1
I: 00
P: 000
M: 001Es geht praktisch ein Ast zum I und am I selber hängen P und M. Somit könnte man das "M" = 001 leider auch als "IS" = 00 1 interpretieren.
volkard schrieb:
ich würde anders sortieren:
S: 1 I: 00 P: 000 M: 001
und da den code auch ändern darf, indem ich an alen codewörter die gleiche stelle invertiere, mache ich draus
S: 0 I: 10 P: 100 M: 101
und
S: 0 I: 10 M: 110 P: 111
nu ist der baum sortiert nach wirtlängen und innerhalb der wortlängen auch alphabetisch.
Ja, der letzte Baum ist eindeutig. Jedoch verstehe ich nicht, wo du festlegst, was invertiert werden darf.
Was sich sehr gut anhört:
volkard schrieb:
ber wichtiger finde ich die andere sache: es reicht, die wortlängen zu wissen. bei einer dicken datei, wo jedes zeichen mal vorkommt, brauchst nur noch die wortlängen abzuspeichern. die rehenfolge ist dann definiert. und die wortlängen kann man vermutlich auch nochmal gut packen
Das man halt eine Art "Wo ist was frei?"-Suche macht, ist eine gute Idee, wozu ich mir nochmal Gedanken zur Umsetzung machen muss.
Müsste es nochmal ausprobieren, aber wenn der Binärbaum IMMER Perfekt ist, dürfte doch ein Ast niemals länger als 8 Bit sein. Ein Ast mit der Länge 0 gibt es halt nicht, deswegen reichen 3 Bit(2^3 = 8 Kombinationen aus Nullen und Einsen) völlig aus, um die Länge der Zeichen zu speichern.
Und da die Zeichen noch nach ihrer Länge sortiert sind, kann man event. auch nur die Differenz in weniger Bit unterbringen.
Also nochmals vielen Dank!
mfg olli
-
Vielleicht bringt es dir auch was, den RFC von Deflate anzusehen. Weiß jetzt aber nicht, ob das vielleicht nicht zu kompliziert wird, weil da nicht nur die Huffman-Kodierung verwendet wird. Aber für ne richtig geile Kompression reicht das alleine eben auch noch nicht.
Ich habe den Thread erst so aufgefasst, als würde es nur um Huffman gehen, aber jetzt scheint ihr ja schon mit jedem Bit zu geizen, daher ist es evtl. ratsam, noch ein bisschen weiter zu schauen.
-
Vertex schrieb:
volkard: Hmm wie Korbinian schon sagte, kann man leider doch nicht die Codes beliebig austauschen. (Auch wenn sie gleicher Länge sind, und nur einmal vorkommen)
Eben bei:
S: 1
I: 00
P: 000
M: 001Es geht praktisch ein Ast zum I und am I selber hängen P und M. Somit könnte man das "M" = 001 leider auch als "IS" = 00 1 interpretieren.
ok. wie vertauschen gar nix.
I: 00
P: 010
M: 011
S: 1ich sortiere nach anzahl und bei gleicher anzahl nach alphabet.
S: 1
I: 00
M: 011
P: 010wenn ich jetzt nur das erste bit angucke, sehe ich, daß die wörter falschrum sortiert sind. deswegen invertiere ich überall das erste bit.
S: 0
I: 10
M: 111
P: 110das zweite bit ist gut.
das dritte wird auch invertiert.
S: 0
I: 10
M: 110
P: 111aber geht das immer?
mal testen
A: 110
B: 111
C: 010
011
E: 100
F: 101
G: 001
H: 000naja, das erste mal invertieren.
A: 010
B: 011
C: 110
111
E: 000
F: 001
G: 101
H: 100nee, nur invertieren kann nicht gehen. es muss auch getauscht werden.
wie kamst du nochmal durch tauschen auf einen uneindeutigen code? das kann ich gar nicht verstehen, daß man nicht wild wörter der gleichen länge tauschen darf.
-
Jup, die Sache mit dem freien Platz hat sich als funktionstüchtig herausgestellt.
wie kamst du nochmal durch tauschen auf einen uneindeutigen code? das kann ich gar nicht verstehen, daß man nicht wild wörter der gleichen länge tauschen darf.
In dem Sinne hatte ich nicht den Code zweier Zeichen getauscht, sondern selber einen generiert.
Was ich mich jetzt Frage:
Wenn es ein Zeichen mit der kleinsten Astlänge n und ein Zeichen mit der größten Astlänge m gibt, muss doch zwischen n und m alle Längen vorhanden sein. Also meinetwegn n = 2 und m = 6, dann kann man doch davon ausgehen, dass es Zeichen mit der Astlänge 3, 4 und 5 mind. einmal gibt. ?oderDas wäre somit eine Fehlerprüfung. Event. sogar eine ungenutzte Information.
Weiterhin kann man doch auch anhand des Dekodierten Textes prüfen, ob die Häufigkeit der Zeichen korrekt war. Ist event. auch noch eine ungenutzte Information.
Zumindest bräuchte man dann in WinRAR oder so keine CRC Fehlererkennung
Jedenfalls wenn das mit m und n so hinhaut, dann bräuchte man wirklich immer nur das Zeichen+Astlänge abzuspeichern, und niemals den Code selber.
mfg olli
-
Hmm, meinst du wirklich, dass Zeichenhäufigkeiten überprüfen sicherer ist als CRC?