基于哈夫曼编码与香农 - 范诺编码性能对比的matlab仿真分析(P124302041张力升)

📅 2026/6/30 22:20:25
基于哈夫曼编码与香农 - 范诺编码性能对比的matlab仿真分析(P124302041张力升)
一、摘要变长无失真编码是信息论中实现信源压缩的核心技术其中哈夫曼编码与香农 - 范诺编码是最典型的两种前缀编码方式。为研究两种编码的压缩性能与码字稳定性差异本文分别对均匀信源与中度偏斜信源进行 MATLAB 仿真计算信源熵、平均码长、编码效率、码长方差并生成完整编码对照表。通过量化对比分析两种编码在不同概率分布下的压缩能力、码长均匀性总结两种编码的优缺点与适用场景。二、 基本理论2.1 信源熵信源熵表征信源平均信息量是无失真编码的理论最低平均码长2.2 平均码长2.3 编码效率效率数值越接近100%压缩性能越优异。2.4 码长方差用来评判各个码字长度波动幅度反映译码时序稳定性方差越小码字长短差距越小硬件传输与缓存设计越简单。2.5 编码原理哈夫曼编码自下而上构建编码树不断合并当前概率最小的两个符号分配 0、1 分支。全局优化加权码长是最优二元前缀码缺陷为概率差距大时长短码悬殊码长方差偏高。香农 - 范诺编码符号按概率从大到小排序后自上而下将符号组划分为总概率尽可能均等的左右子集左分支补 0、右分支补 1 递归划分。算法构造简单但只能实现次优编码。按概率降序排序后自上而下二分分组保证组间概率近似相等属于次优前缀码。三、实验信源与仿真环境3.1 实验信源设共设置两组五符号离散信源1.均匀信源P[0.2, 0.2, 0.2, 0.2, 0.2]2.中度偏斜信源P[0.35, 0.17, 0.17, 0.16, 0.15]通过两种分布对比可以有效区分均匀、非均匀信源下两种编码的性能差异。3.2 仿真程序设计基于 MATLAB 编写完整仿真程序实现信源熵、平均码长、编码效率、码长方差自动计算生成并打印完整哈夫曼、香农 - 范诺编码表绘制平均码长、编码效率、码长方差对比柱状图程序采用单文件嵌套子函数结构代码完整、可独立运行。四、完整仿真代码clear; clc; close all; %% 两组测试信源 source_set { [0.2, 0.2, 0.2, 0.2, 0.2], ... % 均匀信源 [0.35, 0.17, 0.17, 0.16, 0.15] ... % 中度偏斜信源 }; source_name {均匀信源, 中度偏斜信源}; % 存储结果 H_all zeros(1,2); L_huff zeros(1,2); L_sf zeros(1,2); eta_huff zeros(1,2); eta_sf zeros(1,2); var_huff zeros(1,2); var_sf zeros(1,2); % 存储编码表 huff_codes cell(1,2); sf_codes cell(1,2); for s 1:2 p source_set{s}; n length(p); syms cell(1, n); for i 1:n syms{i} [x, num2str(i)]; end % 1. 计算信源熵 H -sum(p .* log2(p)); H_all(s) H; % 2. 哈夫曼编码 [dict_h, Lh] huffmandict(syms, p); len_h cellfun(length, dict_h(:,2)); var_h sum(p(:) .* (len_h - Lh).^2); L_huff(s) Lh; eta_huff(s) H / Lh; var_huff(s) var_h; huff_codes{s} dict_h; % 保存哈夫曼编码表 % 3. 香农-范诺编码 [code_sf, Lsf] ShannonFano(p); len_sf cellfun(length, code_sf); var_s sum(p .* (len_sf - Lsf).^2); L_sf(s) Lsf; eta_sf(s) H / Lsf; var_sf(s) var_s; sf_codes{s} code_sf; % 保存香农-范诺编码表 end %% 打印详细结果 for s 1:2 p source_set{s}; n length(p); fprintf(%s\n, source_name{s}); fprintf(信源熵 H %.4f bit/符号\n\n, H_all(s)); % 打印哈夫曼编码表 fprintf(【哈夫曼编码表】\n); fprintf(%-6s %-8s %-8s %-6s\n, 符号, 概率, 码字, 码长); fprintf(%-6s %-8s %-8s %-6s\n, ----, ----, ----, ----); dict_h huff_codes{s}; for i 1:n code_str num2str(dict_h{i,2}); % 将数值数组转为字符串 fprintf(x%-5d %-8.2f %-8s %-6d\n, ... i, p(i), code_str, length(dict_h{i,2})); end fprintf(\n); % 打印香农-范诺编码表 fprintf(【香农-范诺编码表】\n); fprintf(%-6s %-8s %-8s %-6s\n, 符号, 概率, 码字, 码长); fprintf(%-6s %-8s %-8s %-6s\n, ----, ----, ----, ----); code_sf sf_codes{s}; for i 1:n fprintf(x%-5d %-8.2f %-8s %-6d\n, ... i, p(i), code_sf{i}, length(code_sf{i})); end fprintf(\n); % 打印统计指标 fprintf(【统计指标】\n); fprintf(哈夫曼平均码长%.4f效率%.2f%%码长方差%.4f\n, ... L_huff(s), eta_huff(s)*100, var_huff(s)); fprintf(香农-范诺平均码长%.4f效率%.2f%%码长方差%.4f\n\n, ... L_sf(s), eta_sf(s)*100, var_sf(s)); fprintf(----------------------------------------\n\n); end %% 绘图 figure(Name,平均码长对比); bar([L_huff; L_sf]); set(gca, XTickLabel, source_name); legend(哈夫曼编码, 香农-范诺编码, Location,northwest); ylabel(平均码长 $\bar{L}$, Interpreter, latex); title(两种信源下两种编码平均码长对比); grid on; figure(Name,编码效率对比); bar([eta_huff; eta_sf]); set(gca, XTickLabel, source_name); legend(哈夫曼编码, 香农-范诺编码, Location,northwest); ylabel(编码效率 $\eta$, Interpreter, latex); title(两种信源下两种编码效率对比); grid on; figure(Name,码长方差对比); bar([var_huff; var_sf]); set(gca, XTickLabel, source_name); legend(哈夫曼编码, 香农-范诺编码, Location,northwest); ylabel(码长方差 $\sigma^2$, Interpreter, latex); title(两种信源下两种编码码长方差对比); grid on; %% 子函数区 function [code, avg_L] ShannonFano(p) n length(p); [prob, idx] sort(p, descend); code cell(1, n); code sf_recur(prob, 1, n, , code); tmp cell(1, n); for i 1:n tmp{idx(i)} code{i}; end code tmp; avg_L sum(p .* cellfun(length, code)); end function code sf_recur(prob, st, ed, prefix, code) if st ed code{st} prefix; return; end cum cumsum(prob(st:ed)); total cum(end); min_diff inf; split_k 1; for k 1:length(cum)-1 diff abs(2*cum(k) - total); if diff min_diff min_diff diff; split_k k; end end mid st split_k - 1; code sf_recur(prob, st, mid, [prefix 0], code); code sf_recur(prob, mid1, ed, [prefix 1], code); end五、仿真结果分析5.1 编码结果均匀信源中度偏斜信源5.2 仿真结果分析仿真图表仿真数据实验数据分析1.均匀信源结果分析1所有符号出现概率完全相等香农 - 范诺分组划分方式和哈夫曼编码树结构等效2平均码长、编码效率、码长方差三项参数完全一致3编码效率 96.75%距离信源熵极限差距很小压缩效果优良4码字长度仅有 2 位、3 位两类码长波动固定方差固定为 0.24。2.中度偏斜信源结果分析1平均码长哈夫曼2.30 香农范诺2.31 哈夫曼可以给最高概率符号分配更短码字从整体上压低加权平均码长。2编码效率哈夫曼 97.08% 香农 - 范诺 96.66% 印证哈夫曼是最优前缀码在概率不均匀信源下压缩性能更优越。3码长方差哈夫曼方差 0.91 大于香农 - 范诺 0.2139 这是由于香农范诺均分概率的构造方式让各个码字长度差距不会过大工程传输中译码缓存压力更小稳定性更强。六、总结与讨论1.信源符号概率均匀分布时哈夫曼编码与香农 - 范诺编码性能无区别平均码长、效率、码长方差完全相同。2.信源概率出现差异化中度偏斜时哈夫曼编码拥有更小平均码长与更高编码效率压缩能力最优代价是码字长短差距变大码长方差更高。3.香农 - 范诺编码无法做到全局最优压缩但码字长度分布更加平缓均匀方差更低硬件实现简单适合对码长稳定性要求高的场景。4.整体规律信源概率分布越不均衡哈夫曼编码相较于香农–范诺编码的压缩优势会愈发明显。5.仿真结果成功验证了两种经典编码算法的理论特性。