huffman编译码

简介: huffman编译码

1.算法描述

    利用哈夫曼编码进行信息通信可以较大提高信道利用率,缩短信息传输时间,降低传输成本。但是,这要求在发送端通过一个编码系统对待传数据预先编码;在接收端将传来的数据进行译码(复原)。对于双工信道(即可以双向传输信息的信道),每端都需要一个完整的编/译码系统。试为这样的信息收发站写一个哈夫曼码的编译码系统。
   ​​​​​​哈夫曼编码(Huffman Coding),又称霍夫曼编码,是一种编码方式,哈夫曼编码是可变字长编码(VLC)的一种。Huffman于1952年提出一种编码方法,该方法完全依据字符出现概率来构造异字头的平均长度最短的码字,有时称之为最佳编码,一般就叫做Huffman编码(有时也称为霍夫曼编码)。

   设某信源产生有五种符号u1、u2、u3、u4和u5,对应概率P1=0.4,P2=0.1,P3=P4=0.2,P5=0.1。首先,将符号按照概率由大到小排队,如图1所示。编码时,从最小概率的两个符号开始,可选其中一个支路为0,另一支路为1。这里,我们选上支路为0,下支路为1。再将已编码的两支路的概率合并,并重新排队。多次重复使用上述方法直至合并概率归一时为止。从图1中(a)和(b)可以看出,两者虽平均码长相等,但同一符号可以有不同的码长,即编码方法并不唯一,其原因是两支路概率合并后重新排队时,可能出现几个支路概率相等,造成排队方法不唯一。一般,若将新合并后的支路排到等概率的最上支路,将有利于缩短码长方差,且编出的码更接近于等长码。这里图1中(a)的编码比(b)好。

    赫夫曼码的码字(各符号的代码)是异前置码字,即任一码字不会是另一码字的前面部分,这使各码字可以连在一起传送,中间不需另加隔离符号,只要传送时不出错,收端仍可分离各个码字,不致混淆。
   实际应用中,除采用定时清洗以消除误差扩散和采用缓冲存储以解决速率匹配以外,主要问题是解决小符号集合的统计匹配,例如黑(1)、白(0)传真信源的统计匹配,采用0和1不同长度游程组成扩大的符号集合信源。游程,指相同码元的长度(如二进码中连续的一串0或一串1的长度或个数)。按照CCITT标准,需要统计2×1728种游程(长度),这样,实现时的存储量太大。事实上长游程的概率很小,故CCITT还规定:若l表示游程长度,则l=64q+r。其中q称主码,r为基码。编码时,不小于64的游程长度由主码和基码组成。而当l为64的整数倍时,只用主码的代码,已不存在基码的代码。
   长游程的主码和基码均用赫夫曼规则进行编码,这称为修正赫夫曼码,其结果有表可查。该方法已广泛应用于文件传真机中。

2.仿真效果预览
matlab2022a仿真结果如下:

1.png

3.MATLAB部分代码预览

 
 
 
% ensure to handle uint8 input vector
if ~isa(vector,'uint8'),
    error('input argument must be a uint8 vector')
end
 
% vector as a row
vector = vector(:)';
 
% frequency
f = frequency(vector);
 
% simbols presents in the vector are
simbols = find(f~=0); % first value is 1 not 0!!!
f = f(simbols);
 
% sort using the frequency
[f,sortindex] = sort(f);
simbols = simbols(sortindex);
 
% generate the codewords as the 52 bits of a double
len = length(simbols);
simbols_index = num2cell(1:len);
codeword_tmp = cell(len,1);
while length(f)>1,
    index1 = simbols_index{1};
    index2 = simbols_index{2};
    codeword_tmp(index1) = addnode(codeword_tmp(index1),uint8(0));
    codeword_tmp(index2) = addnode(codeword_tmp(index2),uint8(1));
    f = [sum(f(1:2)) f(3:end)];
    simbols_index = [{[index1 index2]} simbols_index(3:end)];
    % resort data in order to have the two nodes with lower frequency as first two
    [f,sortindex] = sort(f);
    simbols_index = simbols_index(sortindex);
end
 
% arrange cell array to have correspondance simbol <-> codeword
codeword = cell(256,1);
codeword(simbols) = codeword_tmp;
 
% calculate full string length
len = 0;
for index=1:length(vector),
    len = len+length(codeword{double(vector(index))+1});
end
    
% create the full 01 sequence
string = repmat(uint8(0),1,len);
pointer = 1;
for index=1:length(vector),
    code = codeword{double(vector(index))+1};
    len = length(code);
    string(pointer+(0:len-1)) = code;
    pointer = pointer+len;
end
 
% calculate if it is necessary to add padding zeros
len = length(string);
pad = 8-mod(len,8);
if pad>0,
    string = [string uint8(zeros(1,pad))];
end
 
% now save only usefull codewords
codeword = codeword(simbols);
codelen = zeros(size(codeword));
weights = 2.^(0:51);
maxcodelen = 0;
for index = 1:length(codeword),
    len = length(codeword{index});
    if len>maxcodelen,
        maxcodelen = len;
    end
    if len>0,
        code = sum(weights(codeword{index}==1));
        code = bitset(code,len+1);
        codeword{index} = code;
        codelen(index) = len;
    end
end
codeword = [codeword{:}];
 
% calculate zipped vector
cols = length(string)/8;
string = reshape(string,8,cols);
weights = 2.^(0:7);
zipped = uint8(weights*double(string));
 
% store data into a sparse matrix
huffcodes = sparse(1,1); % init sparse matrix
for index = 1:numel(codeword),
    huffcodes(codeword(index),1) = simbols(index);
end
 
% create info structure
info.pad = pad;
info.huffcodes = huffcodes;
info.ratio = cols./length(vector);
info.length = length(vector);
info.maxcodelen = maxcodelen;
 
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function codeword_new = addnode(codeword_old,item)
codeword_new = cell(size(codeword_old));
for index = 1:length(codeword_old),
    codeword_new{index} = [item codeword_old{index}];
end
A_039
相关文章
|
7月前
|
机器学习/深度学习 人工智能 供应链
唯品会:使用库存周转API预测补货需求,降低滞销风险
唯品会通过引入库存周转API,利用智能算法精准预测补货需求,显著提升库存周转率,降低滞销风险。该方案整合多源数据,实现自动化补货决策,使预测准确率超95%,滞销率下降10个百分点,资金效率提升20%。
397 1
|
8月前
|
存储 移动开发 算法
ARM 常用汇编指令
下面是ARM架构中常用汇编指令的总结,涵盖数据处理、数据传输、分支跳转、堆栈操作等类别,方便你快速查阅和理解。
459 105
|
7月前
|
机器学习/深度学习 资源调度 自动驾驶
WorldSimBench: 迈向作为世界模拟器的视频生成模型——论文阅读
WorldSimBench提出了一种新框架,旨在将视频生成模型发展为具备物理理解与动作执行能力的世界模拟器。通过构建层次化评估体系(S0-S3)和HF-Embodied数据集,结合显式感知与隐式操作双重评估,推动具身智能体在Minecraft、自动驾驶和机器人等场景中的真实任务表现。
368 4
|
消息中间件 NoSQL Java
订单出现超时未关闭场景解决方案
订单出现超时未关闭场景解决方案
710 5
|
Python
探索 Python 中链表的实现:从基础到高级
链表是一种由节点组成的基础数据结构,每个节点包含数据和指向下一个节点的引用。本文通过Python类实现单向链表,详细介绍了创建、插入、删除节点等操作,并提供示例代码帮助理解。链表在处理动态数据时具有高效性,适用于大量数据变动的场景。文章为初学者提供了全面的入门指南,助你掌握链表的核心概念与应用。
753 0
|
自然语言处理 数据可视化 数据挖掘
闭源与开源嵌入模型比较以及提升语义搜索效果的技术探讨
本文探讨了自然语言处理中嵌入技术的应用,重点在于语义搜索及聚类方法。通过对比不同规模的开源与闭源模型,文章展示了如何利用聚类技术过滤无关结果,提高搜索精度。实验结果显示,较小模型如mxbai在某些任务上表现优异,提示我们在追求高性能的同时不应忽视计算效率与成本效益。最后,文章还介绍了重新排序技术,进一步优化检索结果的相关性。
465 7
闭源与开源嵌入模型比较以及提升语义搜索效果的技术探讨
|
人工智能 自然语言处理 Serverless
方案测评 | AI大模型助力客户音频对话分析
该方案利用阿里云的函数计算、对象存储及智能对话分析技术,实现客户对话的自动化分析,精准识别客户意图,评估服务互动质量,提供数据驱动的决策支持。其特点包括智能化分析、数据驱动决策、低成本、自动化处理、精准识别、实时反馈及成本效益。方案适用于提升企业服务质量与客户体验,尤其在处理海量客户对话数据时表现突出。
|
定位技术 Python
Anaconda老版本Python虚拟环境更新Spyder软件失败的多种解决方法
Anaconda老版本Python虚拟环境更新Spyder软件失败的多种解决方法
464 1
|
小程序
html+css+js实现带有转盘的抽奖小程序
html+css+js实现带有转盘的抽奖小程序
548 0
|
监控 小程序 安全
微信小程序使用GoEasy实现websocket实时通讯
手把手的教您用GoEasy在微信小程序里,最短的时间快速实现一个websocket即时通讯Demo。