Algorithm 提供随机存取的整数序列压缩

Algorithm 提供随机存取的整数序列压缩,algorithm,compression,Algorithm,Compression,我有一个小范围的n个整数序列[0,k),所有整数的频率都相同f(因此序列的大小是n=f)∗k)。我现在要做的是压缩这个序列,同时提供随机访问(第I个整数是多少)。实现随机访问的时间不一定是O(1)。我更感兴趣的是以更高的随机访问时间为代价实现高压缩 我还没有尝试过哈夫曼编码,因为它根据频率分配代码(我所有的频率都是相同的)。也许我缺少一些针对这种特殊情况的简单编码 任何帮助或指点都将不胜感激 提前谢谢 PS:已经在cs.stackexchange中询问过了,但是这里也询问了更好的覆盖率,对不起。

我有一个小范围的n个整数序列
[0,k)
,所有整数的频率都相同
f
(因此序列的大小是
n=f)∗k
)。我现在要做的是压缩这个序列,同时提供随机访问(第I个整数是多少)。实现随机访问的时间不一定是O(1)。我更感兴趣的是以更高的随机访问时间为代价实现高压缩

我还没有尝试过哈夫曼编码,因为它根据频率分配代码(我所有的频率都是相同的)。也许我缺少一些针对这种特殊情况的简单编码

任何帮助或指点都将不胜感激

提前谢谢


PS:已经在cs.stackexchange中询问过了,但是这里也询问了更好的覆盖率,对不起。

如果您计算出可能的不同组合的数量并以其日志基数2为基础,您可以找到最好的压缩,我认为在您的情况下不会有那么好。频率为1的16个数字可能会有16条消息!Excel告诉我log base 2 of 16!是44.25,而将它们存储为4位代码只需要64位。(如果每种类型有多个)


我想你在混合随机访问时会遇到问题,因为你所拥有的唯一信息是,在整个序列中,每种类型的元素都有固定的数量。对于整个序列来说,这并不是很多信息,它几乎没有单独说明序列的前半部分,因为你很可能有m前半部分中有一些数字,后半部分中则更少。

如果所有整数的频率相同,则最佳压缩的公平近似值为
ceil(log2(k))
位/整数。您可以在恒定时间内访问这些整数的位数组

如果
k
非常小(如3),上述方法可能会浪费相当多的空间。但是,您可以将固定数量的小整数组合成一个基
k
数,这样可以更有效地将其放入固定数量的位中(您还可以方便地将结果放入标准大小的字中)。在任何情况下,您也可以在固定时间内访问此编码

如果整数的频率不同,最佳压缩可能会从输入的不同部分产生可变比特率,因此简单的数组访问将不起作用。在这种情况下,良好的随机访问性能需要索引结构:将压缩的数据分成大小方便的块,每个块都可以依次解压缩从本质上讲,但这一次受块大小的限制


如果每个数字的频率完全相同,您可能可以利用这一点节省一些空间,但这可能不够值得

范围
[0,k)
中的
n
随机数的熵是
n log2(k)
,即每个数字的
log2(k)
位;这是在不利用精确频率的情况下编码数字所需的位数

f
的可分辨排列的熵复制了
k
元素中的每个元素(其中
n=f*k
):

应用斯特林近似(只有当
n
f
较大时,该近似才适用),得出:

这意味着,如果
n
较大,而
k
较小,则无法利用输入的确切频率获得大量空间


上述斯特林近似的总误差为
O(log2(n)+k log2(f))
,即每个编码数字的
O(log2(n)/n+log2(f)/f)
。这意味着如果
k
太大以至于
f
很小(即,每个不同的数字只有少量副本),您可能可以通过巧妙的编码节省一些空间。但是,问题指出,
k
实际上很小。

我无法想象您如何在保留保证的O(1)随机访问的同时压缩它。您是否愿意接受更差的算法性能,而不仅仅是O(1)的更差常数乘法器性能?如果序列真的是随机的,那么你几乎无法压缩它。你可以对log2(k)位的每个整数使用最小大小表示法,但如果超过这个值,你将受到熵的支配。@eviotto:整数在
[0,k)
,因此它们已经是最小大小的表示形式。然而,我们并不是通过任何想象来谈论一个随机序列,因为它们都有完全相同的频率。如果
k=256
并且数据是完全随机的,我希望每个都有(大部分?)相同的频率。给定每个整数的8位表示形式,我会说它是不可压缩的,没有其他冗余源。因此,分布不是随机的(每个数字的频率相同),而是顺序是随机的还是结构化的?例如,0 0 0 0 1 1 2 2 2 2是可压缩的,但真正的随机重排并没有那么多(至少从长远来看)。流中的结构可能会导致更多的压缩,而不仅仅是考虑频率,即使在极为倾斜的分布中也是如此。压缩[0,k)到ceil(log2 k)位范围内的数字将提供相同的“压缩”不管数字的频率如何,尽管位字段操作有点痛苦。事实上,如果您知道k相对于(比如)2^64很小,您可以通过存储floor(log(k)2^64)来接近最佳压缩64位整数中以k为基数的数字。其余的分析是直接的。这是我在第二段中尝试的最后一个。我改进了第三段,以解释我所说的不同情况。+1。顺便说一下,你可以很容易地计算出理论上的最佳压缩比:(lgama(f*k
log2( n!/(f!)^k ) = log2(n!) - k * log2(f!)
~ n log2(n) - n log2(e) - k ( f log2(f) - f log2(e) )
= n log2(n) - n log2(e) - n log2(f) + n log2(e)
= n ( log2(n) - log2(f) )
= n log2(n/f)
= n log2(k)