关于算法:无需构造树即可预测霍夫曼压缩率

Predict Huffman compression ratio without constructing the tree

我有一个二进制文件,我知道其中每个符号的出现次数。如果要使用霍夫曼算法压缩文件,我需要预测压缩文件的长度。我只对假设的输出长度感兴趣,而不对单个符号的代码感兴趣,因此构造霍夫曼树似乎是多余的。
作为说明,我需要得到类似"包含4个,5个和10个c的38位二进制字符串可以压缩到28位。"的区别,只是文件和字母的大小都大得多。

基本问题是:是否可以在不构建树的情况下完成?

查看贪婪算法:http://www.siggraph.org/education/materials/HyperGraph/video/mpeg/mpegfaq/huffman_tutorial.html
似乎可以在n * log(n)的时间内构造树,其中n是文件中不同符号的数量。这在渐近性上还不错,但是需要为树节点分配内存,并且做很多工作,在我看来,这是浪费的。


压缩文件中每个符号的平均位数的下限不过是输入中所有符号x的熵H = -sum(p(x)*log(p(x)))P(x) = freq(x)/(filesize)。使用此compressed length(lower bound) = filesize*H。这是文件压缩大小的下限。但是不幸的是,在大多数情况下,由于比特不是整数而不是小数,因此无法实现最佳熵,因此在实际情况下,需要构造霍夫曼树以获得正确的压缩大小。但是,可以使用最佳压缩大小来获得可能的压缩量的上限,并决定是否使用霍夫曼。


您可以轻松地修改算法以在数组中构建二叉树。根节点位于索引0,其左节点位于索引1,右节点位于索引2。通常,节点的子节点位于(index*2) + 1(index * 2) + 2。当然,这仍然需要内存分配,但是如果您知道有多少个符号,就可以计算出树中有多少个节点。因此,这是单个数组分配。

我看不到完成的工作真正浪费在哪里。您必须以某种方式跟踪组合逻辑,并且如图所示在树中进行操作非常简单。我知道您只是在寻找最终的答案-每个符号的长度-但是如果不做这些工作,您将无法获得答案。


您可以通过以下方法将霍夫曼编码中每个符号的平均比特数上限:
H(p1,p2,...,pn)1其中H是熵,每个pi是在输入中出现符号i的概率。如果将此值乘以输入大小N,将得到近似的编码输出长度。