Ich habe eine Reihe von 2D-Punkten in einem Array gespeichert. Ich muss es so viel wie möglich komprimieren. Am besten schnell, aber kein Deal Breaker, Kompressionsrate ist das Ziel. Die Regeln sind:
Spezielle Eigenschaften:
Was ich bisher erforscht habe:
Ich habe es nur geschafft, Huffman und BWT zu implementieren, aber keiner von beiden gibt mir eine gute Komprimierungsrate (oder verwende die Haupteigenschaft meines Datensatzes). Ich werde heute die erste Option versuchen.
Ich bin mir sicher, dass es bessere Ideen gibt. Hast du welche? Bist du auf etwas Ähnliches gestoßen und hast etwas wirklich gutes umgesetzt?
Beispiel für ein Dataset, in hex:
%Vor% wo z.B. das Teilchen 15 67 03 73
(letzte Reihe) bedeutet Teilchen bei x = 15 und 67/256, y = 3 und 73/256. Wie Sie sehen, sind die Daten etwas geordnet, aber die Nachkommastellen sind völlig unzusammenhängend.
Erste Option von OP ist geeigneter. Aber es kann weiter verbessert werden.
Wenn es ein Muster in der Punkteverteilung gibt, könnten Sie für Schritt 4 erweiterte Kompressoren ausprobieren: LZ *, BWT oder PPM.
Hier sind die Ergebnisse des experimentellen Vergleichs für die in Schritt 4 verwendeten Methoden. Worst-Case-Szenario wird angenommen: Punkte sind zufällig im Bereich 00.00 .. FF.FF gleichmäßig verteilt (so dass die einzige Kompressionsmöglichkeit ist, Informationen über ihre Reihenfolge zu verlieren ). Alle Ergebnisse werden für 250000 Punkte berechnet:
%Vor%Ich habe die Huffman-Codierung nicht versucht. FSE ist eine Methode, die der arithmetischen Codierung ähnelt. Zahlen nach dem Methodennamen zeigen Konfigurationsparameter: für Elias-Codierung - wie viele Bits werden für die Kodierung der einzelnen Bits verwendet, für die Golomb-Kodierung - wie viele niedrigstwertige Bits bleiben unkomprimiert, für FSE - wie viele höchstwertige Bits sind komprimiert (zusammen mit Bitlänge) ).
Alle Ergebnisse wurden von dieser Quelle produziert: Ссылка
Verschachteln Sie die Bits, die die X- und Y-Koordinaten jedes Punktes darstellen, sortieren und komprimieren.
Zum Beispiel, wenn Sie den Punkt (X, Y) durch die zwei 16-Bit-Zahlen dargestellt haben
(X 15 X 14 X 13 X 12 X 11 X 10 X 9 X 8 X 7 X 6 X 5 X 4 <3> X
Konvertiere es in die folgende 32-Bit-Nummer:
X 15 Y 15 X 14 Y 14 X 13 Y < sub> 13 X 12 Y 12 X 11 Y 11 X 10 Y & sub0; 10X & sub9; Y9XX8Yx8X Y & sub0; > 7 Dies würde Vorteile aus jedem Clustering ziehen, das in den Daten erscheinen könnte, da nahe physisch nahe Punkte in nahen Positionen auf der sortierten Liste erscheinen und ihre Repräsentationen ihre Kopfbits teilen. Aktualisieren : Der Punkt besteht darin, nahe Punkte in der Nähe von Positionen zu sortieren. Wenn Sie X- und Y-Bits mischen, erhalten Sie das, was zu langen Folgen von 32-Bit-Ganzzahlen führt, die identische Werte in ihren Kopf-Bits haben. Wenn Sie dann Deltas machen, werden Sie kleinere Werte haben, wenn Sie nur nach X und dann nach Y sortieren (oder umgekehrt). Die Sache ist, dass Sie es dann als einen k-d Baum betrachten können, jedes Bit teilt den Raum (links / rechts oder oben / unten). Für die ersten Ebenen können Sie komprimieren und dann einfach sagen, wie viele Elemente es auf einer Seite gibt, bis Sie mit nur wenigen Elementen zu den Polen gelangen, die Sie durch explizite Angabe der verbleibenden paar Bits darstellen können. Für die beste Komprimierung müssen Sie die arithmetische Codierung verwenden.
Tags und Links algorithm arrays c++ compression