森林里的蚂蚁要搬家了。蚁后给了工头一句话:“把所有家当装进尽量少的箱子,但一件也不能丢。”工头头疼地看着仓库:三百片完全相同的树叶散落各处,几十颗同样大小的松果躺在不同的角落。他先把相同的树叶叠成一摞——箱子立刻空出一半。可当他向蚁后汇报“还能不能更小”时,老数学家蚂蚁说话了:“不管你的打包技术多厉害,这些家当有一个'理论最小体积',这个数值由家当本身的构成方式决定,谁也突破不了。”这个“理论最小体积”,就是熵。它回答了压缩界的终极问题:数据最多能压到多小?压缩的本质是消除冗余,而信息论给出了这个极限的数学表达式。在这篇文章里,我们会顺着蚂蚁搬家队的打包故事,一步步看清熵是什么、信源编码定理如何设下天花板、霍夫曼编码和算术编码这两代“打包术”怎么逼近极限,以及 ZIP 和机器学习里的表征学习,为什么本质上是同一个“整理行李”的动作。

岗位关联

这一节知识能让 AI 从业者理解模型压缩、特征降维和存储优化的理论基础——知道“极限在哪”,才不会在调参时白费力气。

目录
  1. 可视化演示
  2. 压缩的本质:整理家当的第一步
  3. 信息量与熵:给每件家当称“稀有度”
  4. 信源编码定理:打包师的天花板
  5. 霍夫曼编码:贪心打包法
  6. 算术编码:一根刻度尺装下全仓库
  7. ZIP与LZ77:金牌打包队的组合拳
  8. 压缩与表征学习:让 AI 学会拎重点
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

展示香农熵、信源编码与数据压缩的核心原理,通过符号概率分布和编码树直观理解信息压缩的理论基础。

本节配有交互动效(进入视口后自动加载,约 3KB)。

信息论与数据压缩 香农熵:H(X)=-∑p(x)log p(x)衡量信息量 信源编码:将符号映射为变长码字实现压缩 压缩率:编码后比特数与原始比特数之比 H(X) ≤ L_avg < H(X)+1 香农定理保证平均码长接近熵

压缩的本质:整理家当的第一步

蚂蚁工头第一次整理行李,发现仓库里散落着三百片完全相同的树叶。如果他给每片树叶单独装箱,那就白白浪费了 299 份“重复的劳动”。聪明的做法是把它们叠成一摞,用一个标签写上“三百片树叶”。数据压缩做的事情一模一样:找到这种重复的摆放方式,把它合并掉——在信息论里,这种重复和多余被统称为冗余。压缩率就是衡量整理效果的那把尺子:整理后的箱数相比原来少了几倍。

从蚂蚁的仓库回到计算机的世界,任何可以被压缩的文件里都藏着冗余:文本中反复出现的“the“是冗余,图片中大块相同的颜色是冗余,音频里没有声息的停顿也是冗余。无损压缩做到”箱子里一件东西都没少,解压后和原来一字不差”;有损压缩则主动丢掉感知上最不重要的东西,就像搬家时扔掉生了虫的旧木凳。两者共享同一把尺子——压缩率。

整理的第一步永远是“找重复、合并同类”。没有这一步,后面所有编码技巧都无从谈起;而一旦完成了这一步,我们就会追问一个更深刻的问题:一件家当究竟“多重”才算正常?这就是下一节的信息量。

ratio=original sizecompressed size\displaystyle \text{ratio} = \frac{\text{original size}}{\text{compressed size}}
压缩率大于 1 说明变小了,越大代表压得越狠。
  1. 原始大小压缩前文件占据的存储空间,对应蚂蚁搬家前占用的仓库体积。
    original size\text{original size}
  2. 压缩后大小压缩算法输出的实际规模,对应整理打包后的箱子体积。
    compressed size\text{compressed size}
  3. 比值含义两者相除得到倍数。比率越高,说明冗余消除得越彻底。
    ratio>1\text{ratio} > 1

信息量与熵:给每件家当称“稀有度”

蚂蚁情报员负责记录仓库里每件物品的价值。他发现,判断一件物品“值多少信息”,不看它本身有多大,而看它出现的概率有多低。每天都能见到的松果,看到它一点都不意外,携带的信息量几乎为零;而一块几十年一遇的琥珀,一旦出现就让所有蚂蚁围过来——它的信息量极高。情报员把这个“意外程度”量化成一个公式:概率越低,意外程度越高,信息量越大。

单件物品的意外程度只是起点。蚁后真正关心的,是整间仓库平均每件物品的意外程度——如果把仓库里所有符号的“信息量”按概率加权平均,就得到熵。熵的单位同样是比特,它表示“平均每个符号最少需要多少比特才能无损表达”。仓库里的物品种类越均匀、越没有规律,熵就越大,打包也就越困难。

熵的大小直接决定了搬家难度:全是树叶的仓库熵接近 0,一个标签就能打包;而什么都有、比例平均的仓库熵就大,必须为每种物品单独准备编码。蚂蚁们现在有了“家当混乱度”的尺子,下一步要问:最好的打包师到底能做到多小?

I(x)=−log⁡2p(x)\displaystyle I(x) = -\log_2 p(x)
熵是所有可能符号信息量的期望:它是压缩任务最重要的起跑线。
  1. 求和遍历$\sum_{x \in S}$ 表示遍写信源 $S$ 里的每一个符号。
    ∑x∈S\sum_{x \in S}
  2. 权重相乘$p(x)\log_2 p(x)$ 把每个符号的意外程度乘以它出现的权重。
    p(x)log⁡2p(x)p(x) \log_2 p(x)
  3. 整体取负每一项都是负数,对所有项求和后取负,得到非负的熵值。
    −∑x∈Sp(x)log⁡2p(x)-\sum_{x \in S} p(x) \log_2 p(x)
  4. 熵的含义$H(S)$ 是平均每个符号的信息比特数,也是任何无损压缩无法突破的“理论体积”。
    H(S)≥0H(S) \ge 0

信源编码定理:打包师的天花板

蚁后听说有“理论体积”这回事后不服气,请来了全森林最聪明的打包师:“你是不是箱子不够小,才说什么极限?”打包师摇头:“任何无损打包,平均每件物品占用的标签长度都一定不小于熵。这不是手艺问题,是数学上的能量守恒。”这句“打包界的能量守恒”,就是信息论里最著名的信源编码定理,也叫香农第一定理。

定理说的是两件事:第一,任何无失真的编码方案,平均码长 $L$ 都不可能低于信源熵 $H(S)$;第二,只要算法足够聪明,就总能把平均码长压到比熵多不到 1 比特的范围内。换句话说,熵是地板,而“比地板高 1 比特”是聪明打包师能摸到的天花板。

这条定理让搬家公司从此有了预算表:先算熵,再定 KPI。ZIP 压完的文件再大,也不会小过熵给出的极限;如果有一天你发现某个算法把数据压得比熵还小,那只有两种可能——要么概率模型估错了,要么压缩其实是有损的。理解了这个天花板,我们才能欣赏接下来两代打包术的各自高明之处。

L≥H(S),L<H(S)+1\displaystyle L \ge H(S), \quad L < H(S) + 1
无损压缩存在硬下限:平均码长不能低于熵,但可以无限逼近它。
  1. 平均码长$L$ 表示平均每个符号占用的比特数,是打包师真实达到的成绩。
    LL
  2. 熵下限$H(S)$ 是理论最小平均码长,违反它就意味着丢失信息。
    L≥H(S)L \ge H(S)
  3. 逼近上界存在一种构造让 $L$ 比 $H(S)$ 大不到 1 比特,这是“够聪明”的保证。
    L<H(S)+1L < H(S) + 1

霍夫曼编码:贪心打包法

工头听完定理,决定亲手设计一套打包方案。他的思路很朴素:把仓库里最稀有的两堆物品先合并成一个“大柜子”,给这个柜子统一贴一张标签,下次再遇到它们就只要进柜子内部找;然后重复这个动作,不断把当前最稀有的两堆合并。从下往上看,所有物品被组织成一棵“行李树”,每件物品的标签就是它从树根一路走向自己的那串 0 和 1。这就是霍夫曼编码。

这套方法妙在两点:其一,它是贪心的——每次都只处理当前最小的两个概率,却能得到全局最优;其二,它天然满足前缀码性质——没有任何一个码字是另一个码字的前缀,所以解码时不需要分隔符,扫一遍 0/1 串就能无歧义地还原。高频物品被放在树的高处,路径短;稀有物品被埋在树的深处,路径长,平均码长因此被压到接近熵。

蚂蚁们按这套“行李树”打包后,箱子数量果然大幅减少。但细心的情报员发现一个遗憾:当符号概率不是 2 的整数次幂时,比如 0.15、0.08 这种“不整”的概率,每个符号至少要占用 1 个整数比特位,总会浪费一点点空间。有没有办法连这一点点也省下来?下一节,工头决定不再给每件物品单独贴标签,而把整堆行李看成一个整体来编码。

L=∑i=1Npili,H(S)≤L<H(S)+1\displaystyle L = \sum_{i=1}^{N} p_i l_i, \quad H(S) \le L < H(S) + 1
霍夫曼编码是最优前缀码:在“每个符号单独给一个整数位码字”的前提下,它做到了最好。
  1. 符号概率$p_i$ 是第 $i$ 个符号出现的概率,它决定物品在树上位置的高低。
    pip_i
  2. 码字长度$l_i$ 是第 $i$ 个符号分到的二进制路径长度。
    lil_i
  3. 加权平均把每个符号的码长按概率加权求和,得到真实的平均码长。
    ∑i=1Npili\sum_{i=1}^{N} p_i l_i
  4. 区间保证霍夫曼的平均码长一定落在 $[H(S), H(S)+1)$ 之间,摸到了定理给的上限。
    H(S)≤L<H(S)+1H(S) \le L < H(S) + 1

算术编码:一根刻度尺装下全仓库

霍夫曼编码就像给每件物品单独贴标签,标签的长度必须是整数个比特。而工头在某个深夜想到了一个更疯狂的主意:干脆不给单件物品贴标签,把整堆行李当作一个整体,在一条从 0 到 1 的刻度尺上定位它。他规定:读入第一件物品时,按它的概率把 [0,1) 切成几段,选中属于它的那一段;读入第二件物品时,再在刚刚选中段里按概率切一刀。物品一件件进来,区间一段段缩小,最终整个序列就对应刻度尺上一段极小的区间。

解码时只需要知道这个区间里的任意一个小数,就能反向一步一步还原出整串物品。因为输出的是“整个序列在尺子上的位置”,而不是每个符号各自的整数码长,算术编码可以为很小概率的符号也分配“比 1 比特更少”的平均空间,因此它比霍夫曼更贴近熵极限——在上面的动效里,ARI 那根柱子几乎压到了红线。

蚂蚁们用刻度尺把整仓库行李“折叠”成一个点,理论上终于贴近了熵线。但工头很快发现,这套方法虽然精妙,却要维护一张巨大的概率表。回到实际工程,还有没有更简单粗暴、又能处理海量数据的招?有——ZIP 靠的不是精雕细刻,而是“重复的绝不重复打包”。

Wk=Wk−1×p(xk),length≈−∑k=1Nlog⁡2p(xk)\displaystyle W_k = W_{k-1} \times p(x_k), \quad \text{length} \approx -\sum_{k=1}^{N} \log_2 p(x_k)
算术编码用区间宽度来记录整个序列,总码长近似等于熵乘以符号数,是目前贴近理论极限的主流方法。
  1. 初始区间第一个符号到来前,可用区间宽度为整个刻度尺,即 $W_0 = 1$。
    W0=1W_0 = 1
  2. 逐次缩窄每读入一个符号,区间宽度乘上它的概率,区间越缩越小。
    Wk=Wk−1×p(xk)W_k = W_{k-1} \times p(x_k)
  3. 总长度换算把所有负对数相加,得到定位最终区间所需的比特数。
    −∑k=1Nlog⁡2p(xk)-\sum_{k=1}^{N} \log_2 p(x_k)
  4. 逼近熵值这个长度除以符号数 $N$,就是平均码长,它约等于熵,从而突破整数比特限制。
    1N∑k=1N−log⁡2p(xk)≈H(S)\frac{1}{N}\sum_{k=1}^{N} -\log_2 p(x_k) \approx H(S)

ZIP与LZ77:金牌打包队的组合拳

真到了搬家那天,工头发现一个比“符号频率”更明显的浪费:仓库里有一百片完全相同的树叶排成一排。如果一片片编码,就算每个标签只有 1 比特也要花 100 比特。工头灵机一动,在货单上写了一行字:“从第 3 排开始,连续 100 片树叶,和前面第 50 排的完全一样。”这一行字就取代了 100 次编码。这就是 LZ77 的思想:用一块滑动窗口记住最近见过的内容,一旦发现重复串,就输出一个“距离 + 长度”对,告诉解码器“去前面哪个位置复制多长一段”。

ZIP 实际使用的 DEFLATE 算法,正是 LZ77 和霍夫曼编码的组合拳:先用滑动窗口把重复子串替换成短小的 (距离,长度) 记号,再用霍夫曼编码压缩这些记号本身。解码时滑动窗口不断回放历史,得到的数据与原始文件逐字节一致——所以 ZIP 是标准的无损压缩。文件里重复越多,压缩率越惊人,这也解释了为什么代码文本能压 5 到 10 倍,而已经高度随机的加密数据几乎压不动。

ZIP 的成功证明:在工程世界里,与其费尽心思给每个符号贴最优标签,不如先把明摆着的重复清掉。而信息论的眼光还可以走得更远——当压缩的对象从文本变成神经网络的表征时,蚂蚁整理的就不再是仓库,而是数据本身的“气质”。

log⁡2d+log⁡2l≪8l(l large)\displaystyle \log_2 d + \log_2 l \ll 8l \quad (l \text{ large})
当重复串足够长时,记录一次“距离+长度”的开销,远小于把重复内容原样输出 8 倍长度的比特数。
  1. 距离$d$ 是重复子串距离当前位置的偏移量,代表“去前面第几排找”。
    dd
  2. 长度$l$ 是匹配到的连续重复长度,代表“复制多少片树叶”。
    ll
  3. 左边开销$\log_2 d + \log_2 l$ 是记一次位置和长度大约需要的比特数。
    log⁡2d+log⁡2l\log_2 d + \log_2 l
  4. 右边对比$8l$ 是把 $l$ 个字符按每字符 8 比特原样输出的成本,$l$ 越大优势越明显。
    8l8l

压缩与表征学习:让 AI 学会拎重点

如果蚁后想让远方的蚂蚁朋友快速了解“我们仓库的整体气质”,她不会念完整张清单,而是说:“东西很多,树叶为主,偏绿色,整体很轻。”这几个关键词就是仓库的表征——一种高度压缩后的抽象。机器学习中的表征学习做的是同一件事:把高维输入数据压成一个低维向量,让后续任务只依赖这个“压缩包”。

信息论为表征学习提供了一把精确的手术刀——信息瓶颈。它要求模型学到的表征 $Z$ 与原始输入 $X$ 的互信息尽量小(压得越狠越好),同时保证 $Z$ 与任务标签 $Y$ 的互信息足够大(有用的信息不能丢)。这完美对应了有损压缩的质量权衡:把文件压得越小越好,但不能让解压后失真到无法使用。自编码器、量化模型、embedding 降维,本质上都在实践这条法则。

蚂蚁用几个词概括仓库,AI 用几个比特抓住数据的本质。从熵到信源编码定理,从霍夫曼到算术编码,再到 ZIP 和表征学习,压缩从来不只是“变小”的技术,而是一套关于“什么值得保留、什么可以舍弃”的数学哲学。理解了熵,你就同时理解了文件压缩的极限和深度学习表征的边界。

min⁡ZI(X;Z)s.t.I(Z;Y)≥Ic\displaystyle \min_{Z} I(X;Z) \quad \text{s.t.} \quad I(Z;Y) \ge I_c
信息瓶颈把“压缩”和“保真”翻译成了两个互信息约束,是压缩思想在机器学习中的标准表达。
  1. 输入与表征$X$ 是原始数据,$Z$ 是模型学到的压缩表征。
    X,ZX, Z
  2. 压缩目标$I(X;Z)$ 是表征和输入的互信息,最小化它意味着丢掉尽可能多的冗余。
    min⁡ZI(X;Z)\min_{Z} I(X;Z)
  3. 保留约束$I(Z;Y)$ 是表征与标签的互信息,要求它不低于阈值 $I_c$,保证任务可用。
    I(Z;Y)≥IcI(Z;Y) \ge I_c
  4. 整体类比这个目标函数就是数学化的“越省越好,但关键信息必须留下”。
    min⁡size  s.t.  quality≥threshold\min \text{size} \; \text{s.t.} \; \text{quality} \ge \text{threshold}

AI 应用场景

日志与冷数据存储优化

阶段:数据预处理与存储

解决的问题:服务器日志里 90% 内容是重复的模板和固定前缀,直接落盘既浪费存储又拖慢检索。传统方案是买更大的磁盘,成本高且治标不治本。利用 LZ77 结合霍夫曼的 DEFLATE 压缩,可在写入前把日志流压掉 80%–90%,读取时再无损还原。

具体案例:某公司的 ELK 日志管道每天产生 20 TB 原始日志,启用压缩后实际落盘只有 3 TB。用户查询时由后端透明解压,业务侧完全无感,一年省下数百万存储费用。

大模型量化与权重压缩

阶段:模型部署与推理优化

解决的问题:7B 参数模型以 FP32 存储需要 28 GB 显存,单卡几乎跑不动。模型量化本质是一种有损压缩:把连续的 32 位浮点权重量化到 8 位整数,用熵的视角评估信息损失,在保持精度损失小于 1% 的前提下把模型压到约 1/4 大小。

具体案例:推理团队用 GPTQ 方法把 7B 模型权重从 FP16 量化到 INT4,单卡即可加载,推理吞吐提升 3 倍,评测分数几乎不掉。这里的“率失真权衡”正是压缩理论在 ML 部署里的直系后代。

Embedding 向量降维与检索

阶段:表征学习与向量检索

解决的问题:推荐系统要把数亿用户的交互行为编码成 embedding 向量用于召回,768 维向量直接存储需要几十 TB。借鉴信息瓶颈思想,用一个带瓶颈层的自编码器把 768 维压到 64 维,同时用对比学习保证压缩后向量仍保留与点击行为的相关性。

具体案例:某短视频推荐团队将用户向量从 768 维压到 64 维后,向量检索内存减少 8 倍,召回率只下降 0.3 个百分点,且线上延迟大幅下降。压缩的不只是文件,还有模型对世界的理解。

Python 演示

python61 行
import heapqfrom collections import Counter class HuffmanNode:    def __init__(self, char, freq):        self.char = char        self.freq = freq        self.left = None        self.right = None     def __lt__(self, other):        return self.freq < other.freq def build_tree(text):    freq = Counter(text)    heap = [HuffmanNode(ch, f) for ch, f in freq.items()]    heapq.heapify(heap)    while len(heap) > 1:        a = heapq.heappop(heap)        b = heapq.heappop(heap)        parent = HuffmanNode(None, a.freq + b.freq)        parent.left = a        parent.right = b        heapq.heappush(heap, parent)    return heap[0] def build_codes(node, prefix="", codes=None):    if codes is None:        codes = {}    if node.char is not None:        codes[node.char] = prefix    else:        build_codes(node.left, prefix + "0", codes)        build_codes(node.right, prefix + "1", codes)    return codes def encode(text, codes):    return "".join(codes[ch] for ch in text) def decode(bits, root):    res = []    node = root    for b in bits:        node = node.left if b == "0" else node.right        if node.char is not None:            res.append(node.char)            node = root    return "".join(res) if __name__ == "__main__":    text = "hello huffman compression"    root = build_tree(text)    codes = build_codes(root)    bits = encode(text, codes)    original_bits = len(text) * 8    compressed_bits = len(bits)    print("code table:", codes)    print("original bits:", original_bits)    print("compressed bits:", compressed_bits)    print("compression ratio: %.2f%%" % (100 * compressed_bits / original_bits))    print("lossless roundtrip:", decode(bits, root) == text)
目的:从零实现霍夫曼编码——构建频率树、生成前缀码表、压缩字符串并验证无损还原。
  1. heap = [HuffmanNode(ch, f) for ch, f in freq.items()]把每个字符包装成一个节点,放进最小堆,相当于蚂蚁把每种物品单独成一堆。
  2. while len(heap) > 1:反复取出最小两堆合并,对应“先处理最稀有的两件家当”。
  3. parent = HuffmanNode(None, a.freq + b.freq)合成一个空字符的内部节点,它的频率是两个子节点之和。
  4. parent.left = a` 与 `parent.right = b把两个子节点挂到新节点上,行李树逐渐成形。
  5. codes[node.char] = prefix走到叶子节点时,把从根到叶的 0/1 路径记为码字。
  6. def encode(text, codes)查码表把每个字符替换成比特串,完成压缩。
  7. original_bits = len(text) * 8假设一个字符原本占 8 比特,这是压缩前的成本。
  8. print("lossless roundtrip:", decode(bits, root) == text)解码后再比对原文,验证无损。

常见误区

误区我觉得数据压缩就是不断优化算法,只要算法够强,文件总能压得更小,不存在什么极限。

正解香农的信源编码定理明确指出,平均码长不可能低于信息熵。熵由数据本身的概率分布决定,与算法无关。如果把一个完美压缩过的文件继续压小,说明原来的概率模型没建准,或者压缩过程偷偷丢了信息。搬家公司再厉害,也不能让箱子容积低于家当的“理论体积”。

为何常见:生活中我们总能看到“还有更新压缩算法”的新闻,误以为压缩没有边界,其实这些新闻压的都是冗余尚未榨干的旧算法。

误区霍夫曼编码是最优编码,既然是“最优”,那它的平均码长就应该刚好等于熵。

正解霍夫曼是“最优前缀码”,但最优前缀码的平均码长只能保证落在 $[H, H+1)$ 之间。只有当所有符号概率恰好都是 2 的负整数次幂(如 0.5、0.25、0.125)时,它才能精确达到熵。对任意不规整的概率分布,每个符号至少一比特的整数限制会让它高出熵一点点,算术编码就是为消除这点冗余而生的。

为何常见:“最优”两个字太有迷惑性,让人忽略了它是在“整数比特码字”这个约束下的最优。

误区ZIP 能把文件压小这么多,肯定是把文件里那些“没用的内容”偷偷去掉了,解压出来应该和原文件有差别吧?

正解ZIP 属于无损压缩,解压后与原始文件逐字节一致。它靠的是 LZ77 滑动窗口发现重复子串,再用霍夫曼编码压缩这些记号。它消除的是“冗余”,不是“信息”。你可以用代码里的 roundtrip 验证:解码结果与原文完全相同。所谓“删掉内容”,是有损压缩 JPEG 或 MP3 才做的事。

为何常见:人们常把“压缩”和“有损压缩”混为一谈,因为日常接触的图片、音乐大多是 JPEG 和 MP3,形成了错误印象。

误区熵代表信息量,那熵越大的文件信息量越多,应该更有价值、更难压缩是好事。

正解熵衡量的是“不确定性”和“冗余的稀缺程度”。熵越大,说明数据越接近随机,压缩空间越小。而很多高价值数据恰恰熵很小:一份全篇重复相同格式的财务报表熵很低,但它记录的是关键业务事实。压缩视角下,熵大=难压=比特贵,不代表价值高。

为何常见:“信息量”这个日常词汇自带正面色彩,让人误以为量越大越好,忽略了它在压缩语境下是“成本”的度量。

面试题

Q1. 一个发生概率为 0.5 的事件,其信息量是多少比特?

单选题 · easy

  • A.2 比特
  • B.1 比特← 正确答案
  • C.0.5 比特
  • D.0 比特

答案:B。信息量定义为 $I(x)=-\log_2 p(x)$。当 $p=0.5$ 时,$-\log_2 0.5=1$ 比特。这里把“意外程度”换成掷硬币:正反面各一半,朝上的结果只需 1 位二进制就能描述,所以是 1 比特。

Q2. 香农信源编码定理指出,无损压缩的平均码长:

单选题 · easy

  • A.不高于熵值
  • B.不小于熵值← 正确答案
  • C.恰好等于熵值
  • D.与熵值无关

答案:B。信源编码定理的核心不等式是 $L \ge H(S)$,平均码长不能低于熵。可以理解为熵是搬家打包的理论最小容积,手艺再好也不能把箱子压缩到低于家当的“理论体积”。

Q3. 霍夫曼编码生成的码字集合属于下列哪一类编码?

单选题 · easy

  • A.前缀码← 正确答案
  • B.定长码
  • C.汉明码
  • D.卷积码

答案:A。霍夫曼编码保证没有码字是另一个码字的前缀,所以属于前缀码,解码时不需要分隔符。汉明码和卷积码是纠错码,定长码不会让高频符号变短,都不是霍夫曼的特征。

Q4. 若某信源的熵是 2.5 比特,一个设计良好的霍夫曼编码,其平均码长最可能接近:

单选题 · mid

  • A.1.5 比特
  • B.2.6 比特← 正确答案
  • C.3.5 比特
  • D.4.5 比特

答案:B。霍夫曼编码的平均码长 $L$ 满足 $H(S) \le L < H(S)+1$,即落在 $[2.5, 3.5)$ 区间。1.5 比特低于熵不可能,3.5 不满足严格小于,4.5 更远,只有 2.6 比特合理。

Q5. 与霍夫曼编码相比,算术编码的主要优势是:

单选题 · mid

  • A.编码速度总是更快
  • B.无需事先知道概率分布
  • C.输出码长更贴近熵极限← 正确答案
  • D.一定能将文件压到零

答案:C。算术编码把整条序列映射到区间上的一个小数,不受“每个符号至少 1 个整数比特”的限制,因此平均码长能更贴近熵。它仍然需要概率分布,速度通常比霍夫曼慢,且不可能压到零。

Q6. LZ77 滑动窗口编码的核心输出内容是:

单选题 · mid

  • A.字符频率统计表
  • B.重复子串的距离与长度← 正确答案
  • C.完整的霍夫曼树
  • D.每个字符的定长码

答案:B。LZ77 在滑动窗口内查找已出现的重复子串,输出 (距离,长度) 对,告诉解码器去前面哪个位置复制多长。频率表和霍夫曼树属于第二阶段的统计编码,不是 LZ77 的输出。

Q7. 信息瓶颈方法中,学习表征 Z 的目标是:

单选题 · hard

  • A.最小化 I(X;Z) 并保持 I(Z;Y)← 正确答案
  • B.最大化 I(X;Z) 并压缩标签
  • C.最小化 I(Z;Y) 并最大化 H(Z)
  • D.让 Z 与 X 完全保持一致

答案:A。信息瓶颈公式为 $\min I(X;Z) \text{ s.t. } I(Z;Y) \ge I_c$,即压缩输入表征的同时保留对任务有用的信息。如果让 Z 与 X 完全一致,就是没压缩;如果压缩标签,任务信息就丢了。

Q8. 下列压缩算法或格式中,属于无损压缩的有:

多选题 · mid

  • A.ZIP 文件压缩← 正确答案
  • B.JPEG 图片压缩
  • C.FLAC 音频编码← 正确答案
  • D.PNG 图像存储← 正确答案

答案:ACD。ZIP 用 DEFLATE 无损压缩;FLAC 是无损音频编码;PNG 采用无损压缩存储图像。JPEG 会丢弃人眼不敏感的高频信息,属于有损压缩,解压后无法恢复原始像素。

Q9. 关于霍夫曼编码,下列说法正确的有:

多选题 · mid

  • A.高频符号获得较短码字← 正确答案
  • B.码字集合满足前缀性← 正确答案
  • C.平均码长距熵不超过一比特← 正确答案
  • D.均匀分布时一定达到熵极值

答案:ABC。高频符号路径短、低频路径长;前缀性保证无歧义解码;信源编码定理保证 $L < H+1$。D 错误:均匀分布如 5 个等概率符号,熵约 2.32 比特,但霍夫曼需要 3 位定长码,达不到熵。

Q10. 关于算术编码,下列说法正确的有:

多选题 · hard

  • A.用 [0,1) 区间中的小数表示整条序列← 正确答案
  • B.每读入一个符号就按概率缩小当前区间← 正确答案
  • C.输出码长在任意情况下都严格等于熵
  • D.精度受限时可能出现解码失败← 正确答案

答案:ABD。算术编码确实把整串符号折叠成区间里的一个点,并逐符号把区间宽度乘以概率。由于精度有限,逼近熵但极少严格等于熵;一旦区间小到浮点无法区分,解码就会失败。C 的“严格等于”过于绝对。