Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/visual-studio-code/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 压缩唯一排序数序列_Algorithm_Compression - Fatal编程技术网

Algorithm 压缩唯一排序数序列

Algorithm 压缩唯一排序数序列,algorithm,compression,Algorithm,Compression,我正在做一个项目,我有一个数字序列(大约20亿)。每个数字为4字节且唯一。这些数字已排序。我的目标是尽快以未压缩的格式将它们读入RAM。它不关心硬盘空间 如果我不压缩存储它们,我需要20亿*4字节=8GB。这将需要大约100秒来读取。我可以将数据存储为一个位序列,这将需要20亿/8=250MB。这将需要大约3秒钟的时间来读取 我需要使用普通硬盘在0.1-0.5秒(如果可能)的时间内读取并解压缩它们。我不关心压缩数据需要多长时间,但我真正关心的是解压缩数据需要多长时间,我需要在几毫秒内完成 这些数

我正在做一个项目,我有一个数字序列(大约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个数字。

以下是两种可能的方法:

  • 询问者建议将数字序列存储为位字符串。例如:如果数字i在序列中,则位字符串的第i位设置为1,否则为零。首先要尝试的自然是对这个位字符串应用标准压缩算法,看看会发生什么

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


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

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

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

    因此,位向量是最好的

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

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

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


    因此,底线是,不可能将所描述的序列压缩到最新问题中指定的程度。

    如果不知道数字的统计信息,您将得到的答案将只是人们告诉您尝试这个库或那个库的随机猜测。这些数字是唯一的,所以你可能无法直接使用它们。您必须首先在数据中找到一些冗余。例如,您是否分析了序列号差异的统计数据,以便尝试对这些差异使用差分编码器?@dpmcmlxxvi:对于一个单词,我正在存储该单词出现的句子数。您是如何从8GB变为250MB的?4字节数字(大概是整数)和“位序列”的编码有什么不同?@mhum:我不明白你在这里的意思。。。你能换个说法吗?@AlgoCoder:在你的问题中,你说如果你把数据存储为一个位序列,你需要250MB。我不知道你所说的“将数据存储为一个位序列”是什么意思。这帮了大忙。我不太明白你的答案,但似乎是正确的。考虑到问题中的编辑,你有什么新的补充吗?谢谢,我会试试的。