Die Grundidee bei der arithmetischen Komprimierung ist die Möglichkeit, eine Wahrscheinlichkeit mit der genauen Menge der erforderlichen Datenlänge zu codieren.
Diese Datenmenge ist bekannt, durch Shannon bewährt und kann einfach unter Verwendung der folgenden Formel berechnet werden: -log2 (p)
Zum Beispiel, wenn p = 50%, dann müssen Sie 1 Bit. Und wenn p = 25%, benötigen Sie 2 Bits.
Das ist einfach genug für Wahrscheinlichkeiten, die eine Potenz von 2 sind (und in diesem speziellen Fall könnte Huffman-Codierung genug sein). Aber was ist, wenn die Wahrscheinlichkeit 63% beträgt? Dann brauchst du -log2 (0.63) = 0.67 Bits. Sounds tricky ...
Diese Eigenschaft ist besonders wichtig, wenn Ihre Wahrscheinlichkeit hoch ist. Wenn Sie etwas mit einer Genauigkeit von 95% vorhersagen können, benötigen Sie nur 0,074 Bits, um eine gute Schätzung zu liefern. Was bedeutet, dass Sie viel komprimieren werden.
Nun, wie geht das?
Nun, es ist einfacher als es klingt. Sie teilen Ihren Bereich abhängig von Wahrscheinlichkeiten auf. Wenn Sie zum Beispiel einen Bereich von 100, 2 möglichen Ereignissen und eine Wahrscheinlichkeit von 95% für das erste Ereignis haben, dann sagen die ersten 95 Werte "Ereignis 1" und die letzten 5 verbleibenden Werte sagen "Ereignis 2" .
OK, aber auf Computern sind wir es gewohnt, Potenzen von 2 zu verwenden. Zum Beispiel haben Sie mit 16 Bit eine Bandbreite von 65536 möglichen Werten. Tun Sie das Gleiche: Nehmen Sie die ersten 95% des Bereichs (also 62259), um "Event 1" zu sagen, und den Rest, um "Event 2" zu sagen. Sie haben offensichtlich ein Problem des "Rundens" (Genauigkeit), aber solange Sie genügend Werte zum Verteilen haben, spielt es keine Rolle. Außerdem sind Sie nicht auf 2 Ereignisse beschränkt, Sie könnten unzählige Ereignisse haben. Es kommt nur darauf an, dass die Werte abhängig von den Wahrscheinlichkeiten jedes Ereignisses zugewiesen werden.
OK, aber jetzt habe ich 62259 mögliche Werte, um "Event 1" zu sagen, und 3277, um "Event 2" zu sagen. Welches soll ich nehmen ? Nun, jeder von ihnen wird tun. Ob 1, 30, 5500 oder 62256, es bedeutet immer noch "Ereignis 1".
In der Tat, die Entscheidung, welcher Wert ausgewählt wird, hängt nicht von der aktuellen Schätzung ab, sondern von den nächsten.
Angenommen, ich habe "Ereignis 1". Jetzt muss ich einen Wert zwischen 0 und 62256 wählen. Bei der nächsten Schätzung habe ich die gleiche Verteilung (95% Event 1, 5% Event 2). Ich werde einfach die Verteilungskarte mit diesen Wahrscheinlichkeiten zuordnen. Nur diesmal ist es auf 62256 Werte verteilt. Und wir fahren so fort und reduzieren den Wertebereich bei jeder Schätzung.
In der Tat definieren wir "Bereiche", die mit jeder Schätzung enger werden. Irgendwann gibt es jedoch ein Genauigkeitsproblem, da sehr wenige Werte übrig bleiben.
Die Idee ist, den Bereich einfach wieder "aufzublasen". Zum Beispiel wird jedes Mal, wenn der Bereich unter 32768 (2^15) liegt, das höchste Bit ausgegeben und der Rest mit 2 multipliziert (effektiv werden die Werte um ein Bit nach links verschoben). Indem Sie so fortfahren, geben Sie Bits nacheinander aus, da sie durch die Reihe von Vermutungen festgelegt werden.
Jetzt wird die Beziehung mit der Komprimierung offensichtlich: Wenn der Bereich schnell verschmälert wird (zB 5%), geben Sie eine Menge Bits aus, um den Bereich wieder über den Grenzwert zu bringen. Auf der anderen Seite, wenn die Wahrscheinlichkeit sehr hoch ist, verengt sich der Bereich sehr langsam. Sie können sogar viele Vermutungen haben, bevor Sie Ihre ersten Bits ausgeben. So ist es möglich, ein Ereignis auf "einen Bruchteil eines Bits" zu komprimieren.
Ich habe absichtlich die Begriffe "Wahrscheinlichkeit", "raten", "Ereignisse" verwendet, um diesen Artikel generisch zu halten. Aber für die Datenkomprimierung müssen Sie sie nur so ersetzen, wie Sie Ihre Daten modellieren möchten. Zum Beispiel kann das nächste Ereignis das nächste Byte sein; In diesem Fall haben Sie 256 davon.
Jetzt verstehe ich die Frage. –
Sie können eine sehr detaillierte Erklärung für die arithmetische Codierung sowie Algorithmen finden [in diesem Artikel von Arturo San Emeterio Campos] (http://www.arturocampos.com/ac_arithmetic.html). Sie können auch eine C++ - Implementierung für diese Algorithmen in [diesem Beitrag] (http://stackoverflow.com/a/10017164/1009831) sehen. –