Uen*_*enX 9 c++ compression algorithm
我试图压缩一系列非负数,其中:
每个号码只出现一次(这意味着总共有2 ^ N个号码)
N = 4的示例:
[14,1,8,2,12,6,0,10,4,13,5,7,15,9,3,11]
因此通常每个数字将花费4位,对于16个数字,我们将不得不使用16x4 = 64位来存储它们.
目前我刚想到压缩它们如下:
所以压缩的数据大小将是:
Z = 8 * 4 + 4 * 3 + 2 * 2 + 1 * 1 + 1 * 0 = 49 bits
Run Code Online (Sandbox Code Playgroud)
压缩率约为76%,这是相当不错的(我认为).
但是对于较大的N值,该比率似乎会降低(对于N = 2048,该比率仅为91%)
所以我想听听你有关更好压缩的建议.
谢谢.
正如评论中指出的那样,最佳编码(如果所有排列的可能性相同)是将整个排列替换为其在排列枚举中的索引。因为有n 个!可能的排列,索引需要 log 2 n ! 位,因此对每个元素使用 log 2 n位的朴素编码的压缩比是 (log n !)/( n log n )。
使用斯特林近似,我们可以将其重写为 ( n log n - n + O(log n ))/( n log n ),即 1 - 1/(log n ) + O(1/ n ) ,显然渐近逼近1 随着n 的增长。因此, n越大,压缩比下降是不可避免的。
除非并非所有排列都具有相同的概率(并且您有一些有关概率分布的信息),否则不可能实现更好的压缩。