测量Huffman算法的压缩

时间:2012-04-30 14:20:21

标签: compression huffman-code

我正在改进我的编程技巧并实现了霍夫曼算法。现在,我只是考虑没有特殊字符的[a-z]。 a-z的概率值已经从维基百科中使用。

当我运行它时,我会得到大约2倍压缩的随机段落。 但是对于这个计算,我假设原始字母每个需要8位(ASCII)。

但如果我考虑一下,代表26项,我只需要5位。如果我根据这个事实计算,那么压缩系数会下降到接近1.1

所以我的问题是,在现实世界的应用程序中如何确定压缩因子?

第二个问题 - 如果我编写一个使用5位表示a-z的编码器/解码器(比如a = 0,b = 1等) - 这也被认为是一种有效的“压缩”算法吗?

3 个答案:

答案 0 :(得分:1)

你基本上有正确的答案,如果你正在使用的所有内容都是英语的字母频率,你就不能指望大量的压缩。

计算由字母频率知识产生的增益的正确方法是考虑具有相同概率的26符号字母表的熵与英文字母的熵。

(我希望stackoverflow允许像math.stackexchange.com这样的TeX方程式。然后我可以在这里写出不错的方程式。好吧。)

关键公式是-p log(p),其中p是该符号的概率,而log是基数2以得到位的答案。您为每个符号计算此值,然后对所有符号求和。

然后,在理想的算术编码方案中,将以每符号4.70比特编码等概率的26个符号集。对于英语分布(使用Wikipedia article的概率),我们得到每符号4.18位。减少幅度仅为11%左右。

因此,所有频率偏差本身都可以为您买单。 (它在Scrabble乐谱中给你带来了更多,但我离题了。)

我们也可以在霍夫曼编码的近似空间中看同样的事情,其中​​每个代码是一个整数位。在这种情况下,你假设每个字母有5位(浪费了6个代码)。将霍夫曼编码应用于具有相等概率的26个符号给出6个长度为4位的代码和20个长度为5位的代码。这导致平均每个字母4.77位。使用英文字母频率的霍夫曼编码给出了每个字母平均4.21位。减少12%,与熵计算大致相同。

真正的压缩机有很多方法比这更好。首先,他们使用那里的频率而不是他们在英语中的频率来编码文件中的实际内容。这使得它与语言无关,优化实际内容,甚至不编码不存在的符号。其次,您可以将输入分解为多个部分并为每个部分创建新代码。如果这些部分足够大,则传输新代码的开销很小,并且增益通常较大,以便在较小的块上进行优化。第三,你可以寻找更高阶的效果。您可以考虑前一个字母而不是单个字母的频率,并查看给定其前一个字母的下一个字母的概率。现在你有26 ^ 2个概率(仅用于字母)来跟踪。这些也可以针对手头的实际数据动态生成,但现在需要更多数据才能获得增益,更多内存和更多时间。您可以使用三阶,四阶等来获得更高的压缩性能,代价是内存和时间。

还有其他方案可以预处理数据,例如,进行行程编码,查找匹配字符串,应用块变换,标记化XML,增量编码音频或图像等等。暴露熵编码器的冗余,然后利用。我提到了算术编码,它可以用来代替霍夫曼,用不到一点的时间编码非常可能的符号,所有符号用于分数位精度,以便在熵步骤中获得更好的性能。

回到您构成压缩的问题,您可以从任何您喜欢的起点开始,例如:每个字母一个8位字节,对输入进行断言,例如所有小写​​字母(接受如果断言为假,方案失败),然后评估压缩效果。只要在比较两种不同的压缩方案时使用所有相同的假设。您必须注意,任何与数据相关的内容也必须被视为压缩数据的一部分。例如。必须使用该数据块发送从数据块派生的自定义霍夫曼代码。

答案 1 :(得分:0)

对于26个字符,它不是5位,而是log(26)/ log(2)= 4,7位。这是最大熵,但您需要知道特定的熵。对于德语,它是4,0629。当你知道你可以使用公式R = Hmax - H.看这里:http://de.wikipedia.org/wiki/Entropie_(Informationstheoriehttp://en.wikipedia.org/wiki/Information_theory#Entropy

答案 2 :(得分:-1)

如果你对同一文本运行一个不受限制的霍夫曼编码压缩,你会得到相同的结果,所以我认为你说你在同一文本的ASCII编码上获得2倍压缩是合理的。我更倾向于说你的程序正在获得预期的压缩,但目前有一个限制,它无法处理任意输入,以及其他更简单的压缩方案,以便在存在限制的情况下对ASCII进行压缩。 / p>

为什么不扩展算法来处理任意字节值?这样就可以更容易地进行真正的单挑比较。