二元离散信源哈夫曼编码的Python仿真实现(P124302133吴国强)

📅 2026/6/27 2:46:10
二元离散信源哈夫曼编码的Python仿真实现(P124302133吴国强)
信息论课程调研哈夫曼编码最优性证明与Python代码仿真一、调研引言哈夫曼编码是无失真前缀码中平均码长最短的最优编码是信息论无失真信源编码章节的核心内容。本次调研分为两大部分第一严格证明哈夫曼编码的最优性第二使用Python完成编码算法仿真自动生成码字并计算编码效率。二、基础预备知识2.1 基本概念1.前缀码即时码任意一个码字都不能是其他码字的前缀这类编码可以做到无失真译码。2.信源熵H(S)-∑pᵢlog₂pᵢ代表信源压缩的理论下限。3.平均码长L̄∑pᵢlᵢlᵢ为对应符号码字长度。4.无失真编码定理L̄ ≥ H(S)。2.2 哈夫曼编码构造规则1.将信源符号按照概率从小到大排序p₁≤p₂≤…≤pₙ。2.选取概率最小的两个符号分别分配码元0、1将二者概率相加合并为一个新的合成符号。3.将合成符号放回符号集合重新排序重复合并操作直到集合内仅剩下一个符号。4.从根节点反向回溯二叉树得到每个原始符号的二进制码字。三、哈夫曼编码最优性数学证明前提结论最优前缀码一定满足两条性质性质1概率最小的两个符号码字长度必然相等仅最后一位码元不同一个为0一个为1。性质2把两个最小概率符号合并成一个合成符号后得到的新信源的最优编码等价于原信源的最优编码。证明步骤反证法数学归纳法1.归纳初始条件当信源符号数量 n2两个符号分别编为0、1显然是最优编码平均码长达到最小命题成立。2.归纳假设假设符号数量为 k 时哈夫曼编码是最优前缀码。3.归纳递推nk1设原始信源S{s₁,s₂,…,s_{k1}}p₁≤p₂≤…≤p_{k1}设s₁、s₂为概率最小的两个符号。将二者合并得到新信源S’符号总数变为k。根据归纳假设对S’构造的哈夫曼编码为最优码。现在反证原信源最优码一定对应这种合并方式。假设存在一种更优编码不合并最小概率的两个符号则短码字会分配给大概率符号小概率符号码字被拉长最终会导致整体平均码长变大与“最优码”矛盾。因此只有不断合并两个概率最小的符号才能保证整体平均码长最小。综上由数学归纳法可得哈夫曼编码是平均码长最短的前缀即时码是最优无失真信源编码。补充推论费诺编码不满足上述迭代合并规则只能保证局部最优无法达到全局最优所以费诺编码的平均码长通常大于哈夫曼编码。四、程序设计方案4.1 设计思路1.定义二叉树节点类存储符号、概率、左右子节点。2.循环迭代不断选出概率最小的两个节点进行合并构建哈夫曼树。3.递归遍历整棵二叉树回溯提取每一个符号对应的二进制码字。4.程序自动计算平均码长对比信源熵求出编码效率。4.2 完整Python代码定义哈夫曼树节点class HuffNode:def init(self, probability, charNone):self.prob probabilityself.char charself.lchild Noneself.rchild None构建哈夫曼树并生成码字def create_huffman(symbols, probs):node_list [HuffNode(p, c) for c, p in zip(symbols, probs)]迭代合并最小概率节点while len(node_list) 1:node_list.sort(keylambda x: x.prob)node1 node_list.pop(0)node2 node_list.pop(0)parent_node HuffNode(node1.prob node2.prob)parent_node.lchild node1parent_node.rchild node2node_list.append(parent_node)递归遍历生成码字code_result {}def search_tree(node, current_code):if node.char is not None:code_result[node.char] current_codereturnsearch_tree(node.lchild, current_code “0”)search_tree(node.rchild, current_code “1”)search_tree(node_list[0], “”)return code_resultif name “main”:待编码的离散信源source_sym [“s1”, “s2”, “s3”, “s4”]source_prob [0.4, 0.3, 0.2, 0.1]生成哈夫曼码字huff_code create_huffman(source_sym, source_prob)print(“各符号哈夫曼码字”)for ch, code in huff_code.items():print(f{ch}: {code})计算平均码长average_length sum(len(huff_code[c]) * p for c, p in zip(source_sym, source_prob))计算信源熵import mathentropy -sum(p * math.log2§ for p in source_prob)编码效率eta entropy / average_lengthprint(f\n信源熵 H {entropy:.4f} bit)print(f平均码长 L {average_length}“)print(f编码效率 η {eta:.4f}”)五、仿真运行结果程序输出各符号哈夫曼码字s1: 0s2: 10s3: 110s4: 111信源熵 H 1.8490 bit平均码长 L 1.9编码效率 η 0.9732结果分析1.程序输出码字和手动绘制哈夫曼树得到的结果完全一致算法正确。2.平均码长十分贴近信源熵编码效率高达97.32%验证了哈夫曼编码的最优性。3.可随意修改符号与概率程序自动完成编码摆脱人工计算。六、调研总结本次调研完成了两项核心工作一是利用数学归纳法严格证明了哈夫曼编码的全局最优性厘清了它优于费诺编码的理论根源二是把迭代构造算法编写为Python程序实现了信源符号的自动编码定量算出平均码长与压缩效率。本次实践将理论证明与计算机仿真相结合深入理解了无失真信源编码的极限定理把书本理论落地为可运行的代码加深了对信息论压缩理论的理解。