【问题标题】:Compressing sequence of unique sorted numbers [duplicate]压缩唯一排序数字的序列[重复]
【发布时间】:2015-08-08 23:45:41
【问题描述】:

我正在做一个项目,我有一个数字序列(大约 20 亿)。每个数字是 4 个字节并且是唯一的。数字是排序的。我的目标是以未压缩格式尽快将它们读入 RAM。它不关心硬盘空间。

如果我未压缩存储它们,我需要 20 亿 * 4 字节 = 8GB。这将需要大约 100 秒的时间来阅读。我可以将数据存储为位序列,这将需要 20 亿/8 = 250MB。这将需要大约 3 秒的时间来阅读。

我需要使用普通硬盘在 0.1-0.5 秒(如果可能)内读取并解压缩它们。我不在乎压缩数据需要多长时间,但我真的很关心解压缩它们需要多长时间,我需要在几毫秒内完成。

数字的随机性未知。

问题是:使用 i3-i5 CPU,什么样的压缩算法可以将数字压缩到 20-30MB 左右,解压时间为 100-200 毫秒?

编辑:序列的最大数量为 20 亿。这就是为什么我可以将它存储在一个大小为 250MB 的位数组中。序列的大小并不总是 20 亿。它可以包含 1 到 2.000.000.000 个数字。

【问题讨论】:

  • 在不了解数字统计数据的情况下,您将得到的答案只是人们告诉您尝试这个库或那个库的随机猜测。这些数字是独一无二的,因此您可能无法直接使用它们。您必须首先在数据中找到一些冗余。例如,您是否分析了序号差异的统计数据,以尝试对这些差异进行差分编码器?
  • @dpmcmlxxvi:对于一个词,我存储了该词出现的句子数。
  • 你是如何从 8GB 到 250MB 的? 4 字节数字(大概是整数?)和“位序列”之间的编码有何不同?
  • @mhum:我不明白你的意思……你能改写一下吗?
  • @AlgoCoder:在您的问题中,您说如果将数据存储为位序列,则需要 250MB。我不确定您所说的“将数据存储为位序列”是什么意思。

标签: algorithm compression


【解决方案1】:

您将其存储为位序列的方法可以像预期的那样工作,但每个四字节整数需要 512 MiB,而不是 250 MB。

增量编码方案对于密度较小的集合会更好,但不是这个(如原始问题中所述,它是随机选择一半可能的 32 位整数)。在这里,增量 1 将出现大约一半的时间,增量 2 将出现四分之一的时间,依此类推。这将导致 230 + 2x229 + 3x228 + ... = 232 位。与位向量方法相同。

最佳压缩方案将采用 232 的对数基数 2 选择 231 位。结果也是 232 位。 (实际上是 232-16 位,因此可以节省多达 40 亿位中的 16 位。)

所以位向量是最好的。

更新后的问题完全不同。现在这个问题有一个范围很广的一组从一个到所有 31 位整数,并询问如何将其压缩到 20 MiB 到 30 MiB。

这些压缩后的大小限制了集合的大小。给定集合的大小,可以简单地计算该大小的 31 位整数的可能子集的数量,我们称之为 n。可能子集的数量是 231 选择 n"choose" is the binomial coefficient。假设所有此类子集的可能性均等,该可能子集数量的以 2 为底的对数是特定子集的压缩大小的理论最小值(以比特为单位)。

所以现在我们可以计算可以压缩到 20 MiB 到 30 MiB 的最大可能大小。结果是21到3400万。您还可以将大小为 231 的子集 - 21 压缩到 3400 万,因为您可以认为这些子集是由缺失的值而不是存在的值来标识的。在理论上的最佳压缩方案中,介于两者之间的任何内容都需要超过 30 MiB 才能表示。更新后的问题要求提供所有可能的子集,其中绝大多数在 3400 万到 21 亿之间。

因此,归根结底,不可能将所描述的序列压缩到接近更新问题中指定的程度。

【讨论】:

  • 帮助很大。我不完全理解你的答案,但它似乎是正确的。鉴于问题中的编辑,您有什么新内容要添加吗?
【解决方案2】:

这里有两种可能的方法:

  1. 提问者建议将数字序列存储为位串。例如:如果数字 i 在序列中,则位串的第 ith 位设置为 1,否则为 0。尝试的第一件事自然是对这个位串应用标准压缩算法,看看会发生什么。

  2. 从问题的措辞看来,我们可以将序列中的数字视为 4 字节整数。因此,要存储的序列表示可能的 232 个整数中的大约 2*109。这意味着任何两个连续数字之间的平均差异不能超过 ~2.147 = 232 / (2*109)。所以,也许计算差异的顺序并尝试压缩它。由于我预计大部分连续差异将是 1 和 2,因此我怀疑这个序列可能非常可压缩。

【讨论】:

  • 谢谢,我会试试的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-02-03
  • 1970-01-01
  • 1970-01-01
  • 2021-02-09
  • 1970-01-01
  • 2016-01-01
  • 1970-01-01
相关资源
最近更新 更多