2

我想知道我们可以在多大程度上进行无损数据压缩;我无法找到无损算法的在线模拟器来执行一些经验测试。我可以自己做一个,但不幸的是我这段时间没有足够的时间;我仍然对我的直觉感到好奇,我将对其进行解释。

让我们只看两个更流行的算法:Huffman CodingRun-lenght Enconding.

假设我们有一个数字A符号的字母表和该字母表中任意长的符号序列:例如:

Alphabet  = {A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, X, W, Y, Z}
Sequence1 =  SFBJNERUSNJGSDKKDEIJGNMSDJDDSUSJNF
Sequence2 =  MNMNMNREGUHSDFJUF
Sequence3 =  MMMMMNNNNNASDUERJGASIUJMMMNNNUNS

现在,如果我们只用固定长度的n比特字对每个符号进行编码,我们就有了未压缩的序列,也就是长的N比特。

如果我们使用 Huffman 对序列进行编码,我们将使用H位而不是N位,从而节省(1-H/N)*100%位空间。

如果我们使用 RLE 编码相同的序列,我们将使用R位,节省(1-R/N)*100%.

我想知道,如果我们应用RLE + Huffman或者Huffman + RLE我们可以比只使用其中一个来节省更多空间会发生什么。

这对我来说似乎是一个非常基本的想法,但谷歌搜索我没有找到任何关于这个主题的有趣内容。

编辑:嗯,我可能没有考虑到如果我先使用 RLE,我将无法使用 Huffman,因为与单个符号的固定长度代码的对应关系会丢失;但仍然应该可以先使用 Huffman,然后再使用 RLE。

顺便说一句,我对其中的逻辑很感兴趣,我的意思是串联使用多个无损压缩算法。

编辑 2:当我在评论 Mark Adler 的回复时,我意识到我可能已经找到了我的问题的答案。就是这个:

哈夫曼,这是一个符号到符号的代码,如何影响检测?

假设我们有以下代码:AABCABAAB. 在纯二进制中,它将被编码为00 00 01 10 00 01 00 00 01(obv 空格仅出于可读性目的)。霍夫曼将其编码为0 0 11 10 0 11 0 0 11. 空格更多地显示了字符串是如何没有改变的,因此可以检测到完全相同的重复数量,假设我们正在处理这个范围内的代码(符号方面)。

这让我想到了另一点(鉴于这已经是很长的评论,我不会在这里讨论):逐位分析代码。

所以,我实际上认为我得出了一个结论:正如我们所知,任何字典(或基于替换的)编码器将可变数量的符号分组为固定长度的码字,而 Huffman(或任何其他熵编码器)编码固定长度的符号成可变数量的比特,从而将熵逼近到最小值;因此,让霍夫曼先运行是没有意义的(而且只会浪费计算),因为另一种算法很可能会引入更多霍夫曼可以减少的冗余。

当然这只是一篇理论论文,因为在实践中我们可以考虑其他因素(例如计算时间)......更不用说要编码的字符串的不同配置可能导致不同结果的事实。但是,嗯……这对我来说很有意义。:)

4

1 回答 1

5

这类组合是例行公事。您应该阅读一些有关压缩的书籍。

LZ77 是一种更通用的 RLE 形式,它复制先前字符串的重复。(距离为 1 和长度为n的匹配对最后一个字节的n 个副本进行编码。) LZ77 通常后跟霍夫曼、算术或范围编码。

霍夫曼应该遵循 LZ77 或 RLE,而不是在它之前。霍夫曼编码将使检测重复变得更难,而不是更容易。为了首先使用 RLE,您只需将符号集扩展到文字之外。例如,在 zip、gzip、zlib 等中使用的 Deflate 格式具有 286 个符号集来编码 256 个文字字节、29 个长度前缀代码和一个流代码的结尾。29 个长度前缀代码中的每一个都暗示代码后面有一个 0 到 5 位后缀,以添加到基值以获得长度。长度代码及其后缀的存在意味着它后面跟着另一个霍夫曼代码,30 个距离代码前缀之一,每个前缀都有 0 到 13 位的后缀,以指定匹配的距离。

还有许多其他变换(可能会或可能不会自行压缩),然后是熵编码。这些包括 Burrows-Wheeler 变换 (BWT)、通常遵循 BWT 的 Move-To-Front 变换 (MTF)、图像的离散余弦变换(可以无损完成,但最常用于有损压缩算法)等。 数据中的变换组共性以可逆方式,为熵编码步骤提供更多增益。

于 2014-09-11T18:13:24.010 回答