改进数字压缩算法?

时间:2014-01-20 10:59:15

标签: algorithm

我有许多唯一的数字,都是正数,顺序无关紧要,0 < num < 2^32 示例:23 56 24 26

最大的56需要6 bits个空间。所以,我需要:4*6 = 24 bits

我执行以下操作以节省空间:
我先对它们进行排序:23 24 26 56(因为顺序无关紧要)
现在我得到了前者的差异:23 1 2 30

最大的30,需要5 bits个空间 在此之后,我将所有数字存储在4*5 bits = 20 bits空间。

问题:如何进一步改进此算法?

更多信息:根据要求,这些数字大多数位于2.000-4.000范围内。小于300的数字非常罕见。超过16.000的数字也非常罕见。一般来说,所有数字都将接近。例如,它们可能都在1.000-2.000范围内,或者它们都可能在16.000-20.000范围内。数字总数将在500-5.000范围内。

4 个答案:

答案 0 :(得分:4)

您的第一步是好的,因为排序可以将差异减少到最少。这是一种改进算法的方法:

  1. 按照您的方式排序和计算差异。
  2. 在其上使用Huffman coding
  3. 使用霍夫曼编码比你的步骤更重要;我会告诉你原因:

    考虑以下数据:

    1 2 3 4 5 6 7 4294967295
    

    其中4294967295 = 2 ^ 32-1。使用您的算法:

    1 1 1 1 1 1 1 4294967288
    

    所需的总比特仍为32 * 8

    使用霍夫曼编码,频率为:

    1 => 7
    4294967288 => 1
    

    霍夫曼代码为1 => 04294967288 => 1

    所需的总位数= 7 * 1 + 1 = 8位

    霍夫曼编码将大小减小32 * 8/8 = 32次

答案 1 :(得分:4)

这个问题在数据库社区中被称为“反向索引压缩”。你可以谷歌搜索一些文件。

以下是一些最常用的技术:

  • 可变字节编码(VByte)
  • Simple9,Simple16
  • “参考框架”系列技术
    • PForDelta
    • 自适应参照系(AFOR)
  • Rice-Golomb coding(通常用作其他技术的一部分)

VByte和Simple9 / 16最容易实现,速度快,并且在实践中具有良好的压缩比。

霍夫曼编码对于索引压缩不是很好,因为它很慢并且差异在实践中是非常随机的。 (但在你的情况下,它可能是一个不错的选择。)

答案 2 :(得分:2)

你有多少个号码?如果你的集合覆盖范围[0..(2^32)-1]足够密集(你做数学运算)那么4GiB位域,其中n位表示自然数n的存在或不存在可能有用。

答案 3 :(得分:0)

如果您的数字分布不均匀,则可以通过使用数字的频率来实现更好的压缩,并将更少的位数影响到最常用的位数。这是huffman coding背后的想法。