如何压缩一组独特的自然数并比较两个这样的集?

时间:2013-02-28 00:56:11

标签: php algorithm search binary compression

Web应用程序比较成对的正整数。每组只有唯一值,不大于210 000 000(适合28位)。每组最多5 000 000个值。

比较A组和A组B,需要三个结果集:“A独有”,“B独有”,“A& B常见”。特别的任务是回答一个问题“集合S中是否存在数字N?”

到目前为止,该项目在LAMP堆栈下的共享主机的有限资源中运行。我想出的Quick'n'dirty解决方案是将工作外包给托管的MySQL,后者拥有更多资源。每个集合的临时表,唯一带有数字的列是主索引。很少设置足够小以适应引擎=内存,这是快速的。它有效,但速度太慢。

寻找一种方法在内存中保存这样的集合,有效地搜索内部的特定数字。保持内存占用尽可能低。

我想到了将每个集合编码为2 ^ 28位(32 Mb)的位掩码。 set = 1位集中存在的数字。 5百万个数字= 5毫升,由210毫升设定。很多零==可以有效压缩?

好像我正在发明一辆自行车。请指导我对这种特殊二进制压缩情况的“众所周知”解决方案。我读到了霍夫曼编码,这似乎不是正确的解决方案,因为它的重点是缩小尺寸,而我的任务需要在压缩集上进行多次搜索。

更新。刚刚找到Golomb coding上的文章及其application to run-length encooding的示例。

1 个答案:

答案 0 :(得分:3)

有一种标准的压缩技术可用于表示范围内的大型整数集,这允许有效的迭代(因此它可以轻松地进行交集,并集,设置差异等)但不允许随机访问(因此它是没有好处“是S中的N”)。对于这个特殊问题,它会将数据集减少到大约7位,对于大小为5,000,000的集合,大约为8MB。如果它有用,我将在下面描述它。

大小为210,000,000位(大约为26MB)的位向量在计算上是高效的,既可以回答“是S中的N”查询,也可以用于按位运算,因为您可以使用现代处理器上的矢量化指令快速完成它们。它可能和你要获得5,000,000元素的交叉计算一样快。它消耗了大量内存,但如果你有那么多内存,那就去吧。

压缩技术,如果集合是指定大小的均匀分布的随机样本,则简单且几乎是最佳的,如下所示:

  1. 对集合进行排序(或确保对其进行排序)。

  2. 将“当前值”设置为0.

  3. 对于集合中的每个元素,按顺序:

    一个。从元素中减去“当前值”;

    湾虽然该差异至少为32,但输出单个1位并从差值中减去32;

    ℃。输出一个0位,然后输出以五位编码的差值。

    d。将“当前值”设置为比元素

  4. 多一个

    证明压缩将导致每个元素大约七位的声明:

    很明显,每个元素将占用6位(0加上5位delta);此外,我们必须在步骤3b中考虑1位。但请注意,所有增量的总和恰好是集合中的最大元素,不能超过210,000,000,因此,我们不能执行步骤3b超过210,000,000 / 32次。所以步骤3b。将占不到700万比特,而步骤3c将占6 * 5,000,000比特,总共3700万,或每个元素7.4比特(实际上,它通常会比这少一点)。