压缩排序的整数

时间:2009-02-07 13:15:10

标签: indexing compression integer

我正在构建一个索引,它只是在二进制文件中连续存储的几组有序32位整数。问题是这个文件变得非常大。我一直在考虑添加一些压缩方案,但这有点超出我的专业知识。所以我想知道,在这种情况下哪种压缩算法效果最好?此外,解压缩必须很快,因为此索引将用于进行查找。

9 个答案:

答案 0 :(得分:19)

如果要存储靠近的整数(例如:1,3,4,5,9,10等......)而不是一些随机的32位整数(982346 ...,3487623412 ..等)你可以做一件事:

找出相邻数字之间的差异,就像2,1,1,4,1 ...等(在我们的示例中)然后霍夫曼编码这个数字。

如果你直接将它们应用到你拥有的原始数字列表中,我认为霍夫曼编码不会起作用。

但是如果你有一个近似数字的排序列表,你可以通过对数字差异进行霍夫曼编码来获得非常好的压缩比,这可能是比使用LZW算法更好的比例。 Zip库。

无论如何,感谢发布这个有趣的问题。

答案 1 :(得分:8)

整数是以密集方式还是以稀疏方式分组?

密集的我指的是:

[1, 2, 3, 4, 42, 43, 78, 79, 80, 81]

稀疏我指的是:

[1, 4, 7, 9, 19, 42, 53, 55, 78, 80]

如果整数以密集方式分组,则可以压缩第一个向量以保存三个范围:

[(1, 4), (42, 43), (78, 81)]

这是40%的压缩率。当然,这种算法在稀疏数据上不能很好地工作,因为压缩数据占用的空间比原始数据多100%。

答案 2 :(得分:6)

正如您所发现的,N 32位整数的排序序列没有32 * N位数据。这并不奇怪。假设没有重复,每个排序的序列都有N!未排序的seqeuences包含相同的整数。

现在,您如何利用排序序列中的有限信息?许多压缩算法的基础是使用较短的位串来实现常见的输入值(Huffman只使用这种技巧)。几张海报已经建议计算数字之间的差异,并压缩这些差异。他们假设它将是一系列小数字,其中许多将是相同的。在这种情况下,差异序列将被大多数算法很好地压缩。

然而,采取Fibonacci序列。这肯定是排序整数。 F(n)和F(n + 1)之间的差异是F(n-1)。因此,压缩差异序列相当于压缩序列本身 - 它根本没有帮助!

所以,我们真正需要的是输入数据的统计模型。给定序列N [0] ... N [x],N [x + 1]的概率分布是多少?我们知道P(N [x + 1]< N [x])= 0,因为序列被排序。基于差分/霍夫曼的解决方案是有效的,因为它们假设P(N [x + 1] - N [x] = d)对于小正d并且与x无关,因此它们使用可以使用几个位来实现差异很小。如果您可以提供其他模型,则可以对其进行优化。

答案 3 :(得分:2)

如果你需要快速随机访问查找,那么差异的霍夫曼编码(如Niyaz所建议的)只是故事的一半。您可能还需要某种分页/索引方案,以便很容易提取第n个数字。

如果你不这样做,那么提取第n个数字是一个O(n)操作,因为你必须阅读并且霍夫曼解码了一半文件,然后才能找到你所追求的数字。您必须仔细选择页面大小,以平衡存储页面偏移与查找速度的开销。

答案 4 :(得分:1)

我认为Huffman coding对于这个目的来说是非常合适的(与具有类似压缩比的其他算法相比相对较快)。

编辑:我的回答只是一般指针。 Niyaz建议对连续数字之间的差异进行编码是一个很好的建议。 (但是如果列表是有序或者数字的间距非常不规则,我认为使用普通的霍夫曼编码也不会那么有效。事实上,在这种情况下LZW或类似的可能是最好的,虽然可能还不是很好。)

答案 5 :(得分:1)

整数列表中的条件略有不同,但是 问题Compression for a unique stream of data提出了几种可以帮助你的方法。

我建议将数据预过滤为start和一系列offset。如果您知道偏移量可靠地很小,您甚至可以将它们编码为1或2字节数量而不是4字节。如果你不知道这一点,每个偏移量仍然可以是4个字节,但由于它们是小的差异,你将获得比存储原始整数更多的重复。

在预过滤之后,通过您选择的压缩方案运行输出 - 在字节级别上工作的东西,比如gzip或zlib,可能会做得非常好。

答案 6 :(得分:1)

MSalters的答案很有趣,但如果你没有正确分析,可能会分散你的注意力。只有47个Fibonacci数字适合32位。

但他通过分析一系列增量以找到可以压缩的模式来确定如何正确解决问题。

重要的事情:a)是否有重复的价值观?如果是这样,多久一次? (如果重要的话,将它作为压缩的一部分,如果没有使它成为例外。)b)它看起来是准随机的吗?这也可能很好,因为可能找到合适的平均增量。

答案 7 :(得分:0)

在投资你自己的计划之前,我会使用现成的标准。

例如,在Java中,您可以使用GZIPOutputStream来应用gzip压缩。

答案 8 :(得分:0)

也许你可以将连续的32位整数之间的差异存储为16位整数。