【问题标题】:Why Huffman Coding is good?为什么霍夫曼编码很好?
【发布时间】:2014-02-18 11:59:23
【问题描述】:

不是询问霍夫曼编码是如何工作的,而是我想知道为什么它是好的。

我有以下两个问题:

第一季度

我理解霍夫曼编码的最终目的是为某些字符提供更少的位数,从而节省空间。我不明白的是为什么一个char的位数决定与char的频率有关?

Huffman Encoding Trees

有时使用可变长度代码是有利的,其中 不同的符号可以用不同的位数来表示。为了 例如,摩尔斯电码不使用相同数量的点和破折号 对于字母表中的每个字母。特别是 E,最常见的 字母,用一个点表示。

所以在摩尔斯电码中,E 可以用一个点来表示,因为它是最常见的字母。但为什么?为什么它是一个点,因为它是最频繁的?

第二季度

为什么字符的概率/统计对霍夫曼编码如此重要?

如果统计表有误怎么办?

【问题讨论】:

标签: algorithm data-structures huffman-code


【解决方案1】:

如果您为最常用使用的符号分配较少的数字或位或较短的代码字,您将节省大量的存储空间。

假设您想为英文字母分配 26 个唯一代码,并希望根据这些代码存储一本英文小说(仅字母),如果您将短长度代码分配给最常出现的字符,您将需要更少的内存。

您可能已经观察到,重要城市的邮政编码和 STD 编码通常较短(因为它们经常使用)。这是信息论中非常基本的概念。

霍夫曼编码给出前缀码。

哈夫曼树的构造:

n 字符构造霍夫曼树的贪心方法如下:

在 n 个子树中放置 n 个字符。 首先将两个最小权重节点组合成一棵树,将两个叶节点权重之和分配为其根节点的权重。 这样做直到你得到一棵树。

例如考虑下面的二叉树,其中 E 和 T 具有高权重(作为非常高的出现率)

它是一个前缀树。要获取任何字符的霍夫曼代码,从字符对应的节点开始,然后回溯,直到获得根节点。

【讨论】:

  • 能否请您更新您的答案以解释为什么霍夫曼代码的构建算法可以构建前缀树?
【解决方案2】:

确实,E 可以是三个破折号后跟两个点。当您制作自己的编码时,您可以做出决定。如果您的目标是对某个文本进行编码以使结果尽可能短,您应该为最常见的字符选择短代码。 Huffman 算法确保我们获得特定文本的最佳代码。

如果频率表有某种错误,霍夫曼算法仍会为您提供有效的编码,但编码文本会比使用正确频率表时的长度要长。这通常不是问题,因为我们通常会根据要编码的实际文本创建频率表,因此频率表对于我们要编码的文本将是“完美的”。

【讨论】:

    【解决方案3】:

    好吧..您想为出现频率更高的符号分配较短的代码...霍夫曼编码仅通过这个简单的假设起作用.. :-)

    您计算所有符号的频率,将它们全部排序,然后开始为每个符号分配位代码。符号越频繁,分配给它的代码就越短。就这么简单。

    最大的问题是:我们计算这些频率的窗口应该有多大?它应该和整个文件一样大吗?还是应该更小?如果后者适用,有多大?大多数霍夫曼编码都有某种“测试运行”,他们估计最佳窗口大小有点像 TCP/IP 对其窗口帧大小所做的那样。

    【讨论】:

      【解决方案4】:

      霍夫曼编码有两个好处:

      1. 给定一些语料库,它们节省空间

      2. 它们是前缀代码

      例如,给定一组文档,将这些文档编码为 Huffman 码是最节省空间的编码方式,从而节省空间。但是,这仅适用于该组文档,因为您最终得到的代码取决于原始文档集中令牌/符号的概率。统计数据很重要,因为具有最高概率(频率)的符号被赋予最短的代码。因此,最有可能出现在数据中的符号在编码中使用的位数最少,从而提高了编码效率。

      前缀代码部分很有用,因为它意味着没有代码是另一个代码的前缀。在莫尔斯电码中,例如A = dot dashJ = dot dash dash dash,你怎么知道在哪里打破阅读代码。这增加了使用 morse 传输数据的效率低下,因为您需要一个特殊符号(暂停)来表示一个代码传输的结束。将其与每个代码都是唯一的 Huffman 代码进行比较,一旦您在输入中发现符号的编码,您就知道这是传输的符号,因为它保证 不是 是其他符号。

      【讨论】:

        【解决方案5】:

        最常见的字符使用最短的位序列的双重效果可以为您节省成本。

        举个具体的例子,假设您有一段文本,它由 1024 个 e 字符和 1024 个所有其他字符组合而成。

        使用 8 位代码,即以未压缩形式使用的完整 2048 字节。

        现在假设我们将e 表示为单个 1 位,每个其他字母表示为 0 位,后跟其原始的 8 位(霍夫曼的一种非常原始的形式)。

        您可以看到一半的字符已从 8 位扩展到 9 位,得到 9216 位,即 1152 字节。但是,e 字符已从 8 位减少到 1,这意味着它们占用 1024 位或 128 个字节。

        因此使用的总字节数为 1152 + 128,即 1280 字节,表示压缩率为 62.5%。

        您可以使用基于字符的可能频率(例如英文文本)的固定编码方案,或者您可以使用自适应霍夫曼编码,它会随着字符的处理和频率的调整而改变编码方案。虽然前者可能适用于具有高匹配频率概率的输入,但后者可以适应任何输入。

        【讨论】:

          【解决方案6】:

          统计表不会错,因为在一般的霍夫曼算法中,在开头分析空洞文本,并建立给定文本的频繁统计,而莫尔斯有一个静态符号-码图。

          霍夫曼算法利用给定文本的优势。例如,如果 E 是一般英语中最常见的字母,这并不意味着 E 在给定作者的给定文本中是最常见的。

          霍夫曼算法的另一个优点是你可以将它用于从[0, 1]开始的任何字母表完成的中文象形文字,而莫尔斯则只针对英文字母定义

          【讨论】:

            【解决方案7】:
            1. 所以在摩尔斯电码中,“E”可以用一个点来表示,因为它是最常见的字母。但为什么?为什么它是一个点,因为它的频率?
              “E”可以编码为特定码字典的任意唯一码,所以可以为“0”,为了节省内存,我们选择短一点,这样编码后使用的平均字节数就最小化了。

            2. 为什么字符的概率/统计对霍夫曼编码如此重要?如果统计表有误怎么办?
              我们为什么要编码?节省空间对吗?编码后使用的空间是freq(wordi)*Length(wordi),这是我们应该尽量减少的,所以我们选择贪婪地分配高概率短码的单词以节省空间。
              如果统计表有误,那么编码并不是节省空间的最佳方式。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2010-10-17
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多