熵界对照
Shannon 熵给出一个符号流中每字节携带的信息量下限:任何无损编码都无法 低于它——这是信息论的基石。make stats 把每个算法压出的实际 bits/byte 与熵放在同一张表里,让你直观看到"理论极限 vs 工程实现"的差距。
一阶熵(忽略符号之间的顺序关系)定义:
H = -Σ p(x) · log₂ p(x) 单位:bits/byte全语料对照(2.0.0 实测)
数字为 bits/byte;括号内是该算法与熵的差(越小越接近极限)。
| 语料 | 熵 | Huffman | Arithmetic | Range | RLE | LZSS |
|---|---|---|---|---|---|---|
| textlike_10MiB | 5.944 | 5.966 (+0.022) | 5.944 (+0.001) | 6.321 (+0.378) | 39.343 (+33.399) | 8.827 (+2.883) |
| repetitive_10MiB | 7.952 | 7.983 (+0.031) | 7.953 (+0.001) | 8.293 (+0.341) | 0.020 (-7.933) | 0.952 (-7.000) |
| random_1MiB | 8.000 | 8.012 (+0.012) | 8.008 (+0.008) | 8.100 (+0.100) | 39.843 (+31.843) | 8.998 (+0.998) |
| fastq_10MiB | 3.623 | 3.670 (+0.047) | 3.624 (+0.001) | 3.966 (+0.343) | 33.442 (+29.819) | 4.422 (+0.799) |
五个观察
1. 算术编码是最接近熵的算法。 所有语料上 +0.001~0.008 bits/byte, 区间划分不受整数码长限制。Huffman 因每符号至少 1 比特,普遍差 +0.01~0.05。
2. 区间编码的字节输出有固定代价。 稳定差 +0.1~0.38 bits/byte—— 每次重归一化输出整字节而非逐位,这是它与算术编码压缩率差距的全部来源。
3. RLE 和 LZSS 可以"低于"一阶熵——因为熵是模型的,不是绝对的。 repetitive 语料上 RLE 达到 0.020、LZSS 达到 0.952 bits/byte,远低于 一阶熵 7.952。一阶熵假设符号独立,而数据有"长连续重复"这种跨符号结构; RLE/LZSS 恰好是这个结构的专用模型。熵界只对它所基于的模型成立—— 这是信息论里最容易被误解的一点。
4. 无结构数据上熵编码器全部贴住熵。 random 语料熵 8.000,熵编码器 停在 8.01-8.10(只有格式开销),LZSS 因 flag 字节开销停在 8.998, RLE 膨胀到 39.8。随机数据不可压缩不是工程问题,是信息论结论。
5. LZSS 与熵编码是互补维度。 textlike 上 LZSS 差熵 2.9 bits/byte (弱匹配抵不过 flag 开销),fastq 上差 0.8——它的"低于熵"能力只出现在 有跨符号重复的语料上。deflate(gzip)把两者叠加:LZ77 抓结构 + Huffman 抓分布,才是现代压缩器的完整答案。
复现
make build && make test-data
python3 tests/lab_stats.py tests/data/textlike_10MiB.bin # make stats 默认
# 任意语料:
python3 tests/lab_stats.py tests/data/fastq_10MiB.bin2
3
4
换一个输入文件重跑,观察"熵越低 → 压缩率越好"的线性关系——例如把 textlike 换成全部可见 ASCII 的文本,熵会下降,四个算法的输出同步缩小。