当前位置: 首页 > 知识库问答 >
问题:

有“完美”压缩的算法吗?

袁羽
2023-03-14

让我澄清一下,我不是在说完美压缩,也不是说一种能够压缩任何给定源材料的算法,我意识到这是不可能的。我试图得到的是一种算法,它能够将任何源比特串编码到它的绝对最大压缩状态,这取决于它的香农熵。

我相信我听说过一些关于霍夫曼编码在某种意义上是最优的事情,所以我相信这个加密方案可能是基于此的,但这是我的问题:

考虑位串:a="101010101010",b="110100011010"。

使用纯香农熵,当我们将位串视为0和1的简单符号时,这些位串应该具有完全相同的熵,但这种方法是有缺陷的,因为我们可以直观地看到,位串a的熵比位串b的熵小,因为它只是重复10的模式。考虑到这一点,通过计算复合符号00、10、01和11的香农熵,我们可以更好地了解源的实际熵。

这只是我的理解,我可能完全错了,但是根据我的理解,对于一个遍历源是真正随机的,对于一个长度为n的遍历源。所有n长度符号组的统计概率必须是相等的。

我想比标题中的问题更具体一些,我有三个主要问题:

使用单个位作为符号的哈夫曼编码是否会将位字符串压缩为最佳状态,即使我们在2位符号级别分析字符串时会出现明显的模式?如果没有,可以通过在哈夫曼编码的不同“级别”(抱歉,如果我在这里破坏术语)之间循环来优化压缩源,直到找到最佳压缩率吗?在某些情况下,经历不同的哈夫曼编码“循环”会进一步提高压缩率吗?(例如,首先对5位长的符号进行哈夫曼编码,然后对4位长的符号进行哈夫曼编码?huff\u 4bits(huff\u 5bits(bitstring))


共有2个答案

漆雕亮
2023-03-14

没有。可以证明,甚至没有一种算法来确定一个完美的压缩机的性能。见科尔莫戈罗夫复杂性。

哈夫曼编码(或算术编码)本身并不能达到最佳压缩。需要使用其他技术来利用数据中的高阶冗余。

慕凡
2023-03-14

正如马克所说,由于Kolmogorov的复杂性,一般的答案是“不”。让我稍微扩展一下。

压缩基本上分为两个步骤:1)模型2)熵

该模型的作用是“猜测”接下来的字节或字段。模型可以有任何形式,其有效性没有限制。一个简单的例子是随机数生成器函数:从外部角度来看,它看起来像噪声,因此无法压缩。但是如果你知道生成函数,一个无限长的序列可以压缩成一个小的代码集,生成函数。

这就是为什么“没有限制”,Kolmogorov complexity只是说:你永远不能保证没有更好的方法来“建模”数据。

第二部分是可计算的:熵是找到“香农极限”的地方。给定一组符号(通常是模型的输出符号),它们是字母表的一部分,您可以计算最优成本,并找到一种方法来达到经验证的最终压缩极限,即香农极限。

如果您接受每个符号必须使用整数位数进行编码的限制,那么哈夫曼对于香农极限是最优的。这是接近但不完美的近似。更好的压缩可以通过使用分数位来实现,分数位是算术编码器所提供的,或者是最近基于ANS的有限状态熵编码器。两者都更接近香农极限。

香农极限仅适用于“单独”处理一组符号的情况。一旦你试图“组合它们”,或找到符号之间的任何相关性,你就是在“建模”。这是Kolmogorov复杂性的领域,这是不可计算的。

 类似资料:
  • 我希望使用log4j2 RollingFileAppender和定制的压缩算法(ZStd)。 目前为止支持的压缩算法似乎是FileExtension枚举(zip,gz,bz2,...)中的压缩算法,请参见https://github.com/apache/logging-log4j2/blob/efa64bfad3f67c5b5fed6b25d65ef5ca2212011b/log4j-core/

  • 我试图找到一种压缩算法,我可以使用它来编码一个blob,只使用16个固定长度的符号(0b0000-0b1111)。 在没有任何压缩的情况下,我可以使用这16个符号对其各自的位值进行编码(例如,符号5(0b0101)对位0101进行编码,因此如果我的blob是100位长,我需要25个符号来表示它-但这样做不会提供压缩。 我认为我需要的是一个反向霍夫曼(在某种意义上,代码是固定长度的,但它代表可变长度

  • DEFLATE 是同时使用了哈夫曼编码(Huffman Coding)与 LZ77 算法的一个无损数据压缩算法,是一种压缩数据流的算法。任何需要流式压缩的地方都可以用。目前 zip 压缩文件默认使用的就是该算法。 关于算法的原理,以及 哈夫曼编码(Huffman Coding)与 LZ77 算法,感兴趣的读者可以查询相关资料,这里推荐 GZIP压缩原理分析——第五章 Deflate算法详解 序列文

  • 当在Sources(源文件)面板中查看脚本时,单击Pretty-Print(美化)图标,可以将压缩的脚本格式化成方便阅读的形式。 下面是缩略脚本在Sources(源文件)面板中的显示方式: 下面是点击Pretty-Print(美化)图标后显示的同样的脚本:

  • 解析redis的lzf压缩和解压算法

  • 我有两个问题。其中一个会把话题弄得乱七八糟:) 1)我遇到了一个问题,即无法找到关于不同垃圾收集器在Hotspot中如何工作的完整信息。但我不是在谈论垃圾收集器工作的一般描述(我们在互联网上有很多这样的信息),我是在谈论具体的算法。我找到了这本白皮书(Java HotSpot虚拟机中的内存管理)http://www.oracle.com/technetwork/Java/javase/tech/m