我想使用霍夫曼压缩来压缩许多32位数字。
每个数字可能会出现多次,我知道每个数字都会被一些比特序列替换:
111 010 110 1010 1000 等...
现在,问题是:在二进制序列的长度超过32位之前,可以向霍夫曼树添加多少个不同的数字?
生成序列的规则(对于那些不知道的人)是每次添加新数字时,必须为其分配最小的二进制序列,而不是另一个的前缀。
答案 0 :(得分:1)
Huffman是关于压缩的,压缩需要“倾斜”分布才能工作(假设我们正在谈论正常,0阶,熵)。
关于霍夫曼树深度的最坏情况是当算法创建退化树时,即每个级别仅有一个叶子。如果分布看起来像斐波纳契系列,就会发生这种情况。
因此,最差的分布序列如下所示:1,1,1,2,3,5,8,13 .......
在这种情况下,只用33个不同的元素填充完整的32位树。
但是,请注意,要达到32位深度且只有33个元素,最多的元素必须出现3 524 578次。
因此,由于将所有Fibonacci数加起来得到5 702 886,您需要压缩至少5 702 887个数字才能开始无法使用32位霍夫曼树来表示它们。
话虽这么说,使用霍夫曼树来表示32位数字需要相当大的内存来计算和维护树。
[编辑]一种称为“对数近似”的简单格式给所有符号赋予几乎相同的权重。在这种情况下,只需要符号总数。
计算速度非常快:比如300个符号,有些使用8位,有些则使用9位。决定每种类型的公式的公式:
9位:(300-256)* 2 = 44 * 2 = 88; 8位:300 - 88 = 212
然后你可以按照自己的意愿分配数字(最好是使用8位的最常用数字,但这并不重要)。
此版本最多可扩展至32位,这意味着基本没有限制。
答案 1 :(得分:1)
您似乎理解前缀代码的原理。
许多人(令人困惑地)将所有前缀代码称为“霍夫曼代码”。
还有许多其他类型的前缀代码 - 它们都没有将数据压缩成比Huffman压缩更少的位(如果我们忽略了传输频率表的开销),但是它们中的许多都非常接近(有些类型的数据)并具有其他优点,例如运行速度更快或保证一些最大代码长度(“长度限制前缀代码”)。
如果你有大量的独特符号,霍夫曼频率表的开销就会变大 - 或许其他一些前缀代码可以提供更好的净压缩。
许多在硬件中进行压缩和解压缩的人对最大码字大小有固定限制 - 许多图像和视频压缩算法都指定了“长度受限的霍夫曼码”。
最快的前缀码 - universal codes - 实际上涉及一系列可以预先生成的比特序列,而不考虑实际的符号频率。正如您所提到的,使用这些代码的压缩程序将最频繁的输入符号与最短的位序列相关联,将次最频繁的输入符号与下一个短的位序列相关联,依此类推。
例如,某些压缩程序使用Fibonacci codes(一种通用代码),并始终将最频繁的符号与位序列“11”相关联,这是位序列的次最频繁的符号“011”,旁边是“0011”,旁边是“1011”,依此类推。
霍夫曼算法产生的代码在很多方面类似于通用代码 - 两者都是前缀代码。 但是,正如Cyan指出的那样,Huffman算法与那些通用代码略有不同。 如果您有5个不同的符号,则霍夫曼树将包含5个不同的比特序列 - 但是,the Huffman algorithm生成的确切比特序列取决于确切的频率。 一个文档可以具有{10,10,20,40,80}的符号计数,从而导致霍夫曼比特序列{0000 0001 001 01 1}。 另一个文档可能具有{40,40,79,79,80}的符号计数,导致霍夫曼比特序列{000 001 01 10 11}。 尽管两种情况都具有恰好5个唯一符号,但是在这两个压缩文档中,最频繁符号的实际霍夫曼代码是非常不同的 - 一个文档中的霍夫曼代码“1”,另一个文档中的霍夫曼代码“11”。 但是,如果使用Fibonacci代码压缩这些文档,则最常用符号的Fibonacci代码始终相同 - 每个文档中的“11”。
特别是对于Fibonacci,第一个33位Fibonacci码是“31个零位后跟2个1位”,表示值F(33)= 3,524,578。 因此,3224,577个唯一符号可以用32位或更少的Fibonacci代码表示。
前缀码的一个更直观的特征是某些符号(稀有符号)被“压缩”成更长的比特序列。 如果您实际上有2 ^ 32个唯一符号(所有可能的32位数字),则强制压缩器使用限制为32位或更少的前缀代码时,无法获得任何压缩。 如果您实际上有2 ^ 8个唯一符号(所有可能的8位数字),则强制压缩器使用限制为8位或更少的前缀代码时,无法获得任何压缩。 通过允许压缩器扩展稀有值 - 使用超过8位来存储我们知道可以以8位存储的稀有符号 - 或者使用超过32位来存储稀有符号我们知道可以以32位存储 - 释放压缩器使用少于8位 - 或少于32位 - 来存储更频繁的符号。
特别是,如果我使用Fibonacci代码来压缩值表, 其中值包括所有可能的32位数, 必须使用长达N位的斐波纳契码,其中F(N)= 2 ^ 32 - 求解N得到 对于最不常用的32位符号,N = 47位。