信息论实验用matlab实现哈夫曼码编译码
哈夫曼编码及Matlab实现

哈夫曼编码及Matlab 实现
哈夫曼编码是一种所得码字是异前置的变长码,其平均码长最短,被称为最佳变长码,也称为哈夫曼编码。
其具体编码方法如下:
(1)将信源信息(符号)按概率大小排队;
(2)从最小概率的两个消息开始编码,并给予一定的编码规则,如小概率的下支路编为1(或0),大概率的上支路变为0(或1),若两者概率相等,仍是下支路为1上支路为0;
(3)将已经编码的两个消息对应概率合并,并重新按概率大小排队,重复步骤(2);
(4)重复步骤(3),直至合并概率归一为止;
(5)变成的变长码是按后出先编方式,即从概率归一的树根沿编码路线逆行至对应的消息。
实验内容:
给定离散信源:
⎥⎦⎤⎢⎣⎡=⎥⎦⎤⎢⎣⎡01.010.015.017.018.019.020.07654321
u u u u u u u p U 对其进行哈夫曼编码,其理论结果如下:
运行结果:
该结果与理论结果相符,满足实验要求。
【最新精选】霍夫曼编码的matlab实现

霍夫曼编码的matlab实现一、实验内容:用Matlab语言编程实现霍夫曼(Huffman)编码。
二、实验原理及编码思想:霍夫曼(Huffman)编码算法是满足前缀条件的平均二进制码长最短的编-源输出符号,而将较短的编码码字分配给较大概率的信源输出。
算法是:在信源符号集合中,首先将两个最小概率的信源输出合并为新的输出,其概率是两个相应输出符号概率之和。
这一过程重复下去,直到只剩下一个合并输出为止,这个最后的合并输出符号的概率为1。
这样就得到了一张树图,从树根开始,将编码符号1 和0 分配在同一节点的任意两分支上,这一分配过程重复直到树叶。
从树根到树叶途经支路上的编码最后就构成了一组异前置码,就是霍夫曼编码输出。
以本教材P36例题3-2信源为例:离散无记忆信源:U u1 u2 u3 u4 u5P(U) = 0.4 0.2 0.2 0.1 0.1解:通过上表的对信源缩减合并过程,从而完成了对信源的霍夫曼编码。
三、程序设计思路分为两步,首先是码树形成过程:对信源概率进行合并形成编码码树。
然后是码树回溯过程:在码树上分配编码码字并最终得到霍夫曼编码。
1、码树形成过程:将信源概率按照从小到大顺序排序并建立相应的位置索引。
然后按上述规则进行信源合并,再对信源进行排序并建立新的位置索引,直到合并结束。
在这一过程中每一次都把排序后的信源概率存入矩阵G中,位置索引存入矩阵Index中。
这样,由排序之后的概率矩阵G以及索引矩阵Index就可以恢复原概率矩阵P了,从而保证了回溯过程能够进行下去。
2、码树回溯过程:在码树上分配编码码字并最终得到Huffman 编码。
从索引矩阵M 的末行开始回溯。
(1) 在Index的末行2元素位置填入0和1。
(2) 根据该行索引1 位置指示,将索引1 位置的编码(‘1’)填入上一行的第一、第二元素位置,并在它们之后分别添加‘0’和‘1’。
(3) 将索引不为‘1’的位置的编码值(‘0’)填入上一行的相应位置(第3 列)。
哈夫曼编码的MATLAB实现

哈夫曼编码的MATLAB实现本代码灵感来⾃于百度上某篇使⽤sort()函数实现哈夫曼编码的⽂章,原⽂过于复杂。
于是本⼈按照逻辑重写过程得到下述代码,可谓思路清晰,⽅法简洁。
由于试验的量也不是很⼤,所以性能或许不好?嗯……管他的呢唯⼀难读的地⽅在于MAP函数的补全部分,但其实和哈夫曼编码最后⾃顶向下得到编码的过程逻辑⼀致。
sort()函数是MATLAB中⽐较⽅便的⼀个排序函数。
[A,B]=sort(C),其中C为乱序概率序列,可得: 1.A为C的升序序列 2.B为A对应数字在C中的原始位置(1)由 A 我们可以得到C序列中 最⼩值 和 次⼩值 ,⽤于哈夫曼编码中最⼩值和次⼩值相加。
(2)由 B 可以知道两个值在原始序列中的位置,⽤于记录本次加法对应的“ 0 ”和“ 1 ”。
那么我们可以把它记录下来作为哈夫曼编码中加法合并的路径,记作MAP矩阵。
合并后的序列在原序列的基础上⽣成,两项的和统⼀赋值给较⼤值,较⼩值则赋⼀个⽤不到的极⼤值即可,此处⽤5。
[0.2 0.19 0.17 0.18 0.15 0.01 0.1] --->[0.2 0.19 0.17 0.18 0.15 5 0.11]反复操作后,即依次合并最⼩两项,得到合成的全路线如下:补全所有的值后得到完整的MAP,倒着输出就可以下⾯贴上完整的代码。
clc;clear;p=[0.2 0.19 0.17 0.18 0.15 0.01 0.1];n=length(p);List=p;Op_List=p;Map=[];%Map⽤于进⾏huffman 编码,下⾯⽣成(n-1)*(n*n)的矩阵for i=1:n-1Map=[Map;blanks(n)];endfor i=1:n-1[Op_List,e]=sort(Op_List);% e 记录了原来的顺序%e(1)e(2)就是合并的两个数,⼩的赋1⼤的赋0Map(i,e(1))='1';Map(i,e(2))='0';%第⼀第⼆加到第⼆个,第⼀个作废Op_List(2)=Op_List(1)+Op_List(2);Op_List(1)=n;%位置还原Back_List=zeros(1,n);for j=1:nBack_List(e(j))=Op_List(j);endOp_List= Back_List;endx=n;y=n-1;%补全Mapfor i=y:-1:1for j=1:xif Map(i,j)~=' 'for k=i-1:-1:1if Map(k,j)~=' 'for b=1:xif b~=j && Map(k,b)~=' 'Map(k+1:y,b)=Map(k+1:y,j);endendendendendendendMap%输出for j=1:nfprintf(' 概率:%.2f',p(j)); fprintf(' 哈夫曼编码: '); for i=y:-1:1if Map(i,j)~=' 'fprintf('%c',Map(i,j)); endendfprintf('\n');end。
信息论与编码课程作业_huffman编码的matlab_实现

信息论与编码课程作业——霍夫曼编码求信源熵和存储前后的信息量的变化一:设计目的:1、学习离散信源平均信息量的计算方法。
2、理解和掌握huffman 编码的基本原理,实现对信源符号的huffman 编码3、熟悉 Matlab 编程; 二:设计原理和思路1.信源熵的计算:公式: 21()log a I a p = Matlab 实现:I=log2(1/p) 或I=-log2(p) 熵(平均自信息)的计算公式22111()log log qq i i i i i i H x p p p p ====-∑∑Matlab 实现:HX=sum(-x.*log2(x));或者h=h-x(i)*log2(x(i));2.霍夫曼编码原理;分为两步,首先是码树形成过程:对信源概率进行合并形成编码码树。
然后是码树回溯过程:在码树上分配编码码字并最终得到Huffman 编码。
1、码树形成过程:将信源概率按照从小到大顺序排序并建立相应的位置索引。
然后按上述规则进行信源合并,再对信源进行排序并建立新的位置索引,直到合并结束。
在这一过程中每一次都把排序后的信源概率存入矩阵p 中,位置索引存入矩阵m 中。
这样,由排序之后的概率矩阵 p 以及索引矩阵m 就可以恢复原概率矩阵P 了,从而保证了回溯过程能够进行下去。
2、码树回溯过程:在码树上分配编码码字并最终得到Huffman 编码。
从索引矩阵M 的末行开始回溯。
(1) 在p 的末行2元素位置填入0和1。
(2) 根据该行索引1位置指示,将索引1位置的编码(‘1’)填入上一行的第一、第二元素位置,并在它们之后分别添加‘0’和‘1’。
(3) 将索引不为‘1’的位置的编码值(‘0’)填入上一行的相应位置(第3 列)。
(4) 以m的倒数第二行开始向上,重复步骤(1) ~ (3),直到计算至m的首行为止。
三:设计代码:>> clear all;format longdisp(strcat('信息论与编码课程作业——霍夫曼编码求信源熵和存储前后的信息量的变化',13));histgram=zeros(1,255);[c,map]=imread('C:\Documents and Settings\Administrator\桌面\infomation\lenna.bmp');x=rgb2gray(c);[a,b]=size(x);for i=1:afor j=1:bk=x(i,j);histgram(k)=histgram(k)+1;endendf=histgram/a/b;symbols=find(f~=0); %灰度值p=f(symbols); %概率L=length(p);pp=p;%霍夫曼编码m=zeros(L-1,L);for i=1:L-1[p,mark]=sort(p);m(L-i,1:L-i+1)=mark(1:L-i+1);p=[p(1)+p(2),p(3:L),1];endc=cell(L-1,L);c(1,1)={'0'};c(1,2)={'1'};for i=2:L-1;ind=find(m(i-1,:)==1);temp=char(c(i-1,ind));c(i,1)={[temp,'0']};c(i,2)={[temp,'1']};snc=find(m(i-1,:)~=1);for j=3:i+1;con=snc(j-2);c(i,j)=c(i-1,con);endendcodeL=[];averge_long=0;H1=0;disp(strcat('灰度值',32,32,32,'概率',32,32,32,32,32,32,32,32,32,'霍夫曼编码:'));for i=1:L;ind=find(m(L-1,:)==i);code=char(c(L-1,ind));codeLength(i)=length(code);averge_long=averge_long+pp(i)*codeLength(i);H1=H1+pp(i)*log2(1/pp(i));disp(strcat(32,num2str(symbols(i)),32,32,32,num2str(pp(i)),32,32, code));enddisp(strcat('信源熵=',num2str(H1),32,32,32,32,'平均码字长度=',num2str(averge_long),32,32,32,32,32,'压缩比=',num2str(8/averge_long)));四:设计运行结果:信息论与编码课程作业——霍夫曼编码求信源熵和存储前后的信息量的变化灰度值概率霍夫曼编码:30 1.5259e-005 101000111100001031 1.5259e-005 101000111100001136 1.5259e-005 101000111100000037 1.5259e-005 101000111100000139 6.1035e-005 1010001111000140 7.6294e-005 1110010101001041 6.1035e-005 0111010111011042 6.1035e-005 0111010111011143 9.1553e-005 1110010101001144 0.00018311 111011101010145 0.00021362 00111101101146 0.00022888 01110101111047 0.00024414 01110101111148 0.00039673 0011110110049 0.00048828 1010001110050 0.00065613 1110010101151 0.00090027 011101011052 0.00086975 001111011153 0.0013123 111001011054 0.0013733 111011101155 0.0015411 00010101156 0.0018005 01110101057 0.0025177 11010001158 0.0036621 0111111059 0.0033722 0101111060 0.0046539 1100110161 0.0055847 1111010162 0.0061188 001001063 0.0080261 100111064 0.0075226 100001165 0.0083466 101010166 0.0088806 101111167 0.0092773 110011168 0.0095367 110101069 0.0086517 101101070 0.0084229 101011071 0.0075378 100010172 0.0071564 011011173 0.0061493 001001174 0.0056 1111011075 0.0053864 1110110076 0.0045319 1100011177 0.0043488 1011000178 0.0042114 1010111079 0.0039063 1000111180 0.0041199 1010100181 0.0035706 0110101182 0.0039368 1001011083 0.0037537 1000010084 0.003479 0110101085 0.0036011 0111000186 0.0033417 0101101087 0.0032501 0100110088 0.0034027 0110000189 0.0031128 0011010090 0.0031433 0011110091 0.0036774 0111111192 0.0041046 1010011094 0.0038452 1000111095 0.004364 1011100096 0.0037842 1000110097 0.0037079 1000001198 0.0033722 0101111199 0.0040741 10100001 100 0.0040741 10100010 101 0.0038147 10001101 102 0.0040588 10011111 103 0.0041046 10100111 104 0.004364 10111001 105 0.0048218 11010111 106 0.0052185 11100100 107 0.0049591 11011010 108 0.005188 11100001 109 0.0047455 11010110 110 0.0052032 11100011 111 0.0054474 11110100 112 0.0057526 11111011 113 0.0065308 0100111 114 0.0079346 1001100 115 0.010223 1101111116 0.0095825 1101100 117 0.0089417 1100000 118 0.0086975 1011011 119 0.0081787 1010010 120 0.007782 1001001121 0.0066376 0101011 122 0.0059357 11111111 123 0.0056458 11110111 124 0.0051575 11100000 125 0.0052948 11101001 126 0.005188 11100010 127 0.0059814 0000001 128 0.0058594 11111101 129 0.0065613 0101010 130 0.0062561 0011011 131 0.006897 0110100132 0.0072479 0111011 133 0.0073242 0111110 134 0.007309 0111101135 0.0075226 1000100 136 0.0077515 1001000138 0.008606 1011001139 0.0091095 1100100 140 0.012115 000010141 0.012115 000011142 0.012741 001110143 0.012329 001100144 0.010941 1111001145 0.010147 1101110146 0.0089417 1100001 147 0.0088043 1011101 148 0.0091095 1100101 149 0.010712 1110101150 0.011337 1111100151 0.010513 1110011152 0.012878 010000153 0.012268 001010154 0.013138 010100155 0.012238 001000156 0.012939 010001157 0.012115 000100158 0.012955 010010159 0.012207 000111160 0.011993 000001161 0.013916 011001162 0.012177 000110163 0.012299 001011164 0.0094604 1101001 165 0.0089874 1100010 166 0.0088501 1011110 167 0.0056915 11111010 168 0.0059357 0000000 169 0.0071716 0111001 170 0.0057678 11111100 171 0.0054016 11101111 172 0.0054169 11110001 173 0.0058746 11111110 174 0.0072937 0111100 175 0.0070953 0110110 176 0.006424 0011111177 0.0061035 0001011 178 0.0054016 11110000 179 0.0053864 11101101 180 0.0046692 11010000182 0.0036774 10000000183 0.0033875 01100000184 0.0033264 01011000185 0.0031281 00110101186 0.0035706 01110000187 0.0033264 01011001188 0.0033569 01011011189 0.0036011 01110100190 0.0040436 10011110191 0.0034485 01100010192 0.0036774 10000001193 0.0032654 01001101194 0.0034485 01100011195 0.003006 00010100196 0.0033722 01011100197 0.0036774 10000010198 0.0042419 10110000199 0.0045166 11000110200 0.0041046 10101000201 0.0052643 11101000202 0.0050354 11011011203 0.0045319 11001100204 0.0039825 10011010205 0.0040588 10100000206 0.0039673 10010111207 0.0037537 10000101208 0.0033722 01011101209 0.0026703 111011100210 0.0022125 110100010211 0.0018768 101000110212 0.0015259 000101010213 0.0013428 1110010111214 0.0012665 1110010100215 0.0007782 0011110100216 0.00079346 0011110101217 0.00061035 10100011111218 0.00054932 10100011101219 0.00065613 11101110100220 0.00035095 111011101011 221 0.00033569 111001010101 222 0.00030518 101000111101 223 0.00021362 011101011100 224 0.00016785 1110111010100225 0.00019836 001111011010226 0.00015259 1110010101000227 0.00010681 0111010111010228 6.1035e-005 10100011110010230 3.0518e-005 101000111100110231 1.5259e-005 10100011110011110232 1.5259e-005 10100011110011111233 1.5259e-005 1010001111001110信源熵=7.2193 平均码字长度=7.2492 压缩比=1.1036五:设计新得体会:通过这学期对信息论和编码的学习,以及这次的设计,使我了解了很多东西,也使以前所学的知识得以巩固!,通过这次的设计,进一步学习了离散信源平均信息量、平均码长和压缩比的计算方法。
(完整word版)huffman编码的matlab实现

Huffman编码的matlab实现一、信源编码介绍为了减少信源输出符号序列中的剩余度、提高符号的平均信息量,对所施行的变换。
具体说,就是针对信源输出符号序列的统计特性来寻找某种方法,把信源输出符号序列变换为最短的码字序列,使后者的各码元所载荷的平均信息量最大,同时又能保证无失真地恢复原来的符号序列。
既然信源编码的基本目的是提高码字序列中码元的平均信息量,那么,一切旨在减少剩余度而对信源输出符号序列所施行的变换或处理,都可以在这种意义下归入信源编码的范畴,例如过滤、预测、域变换和数据压缩等。
当然,这些都是广义的信源编码。
一般来说,减少信源输出符号序列中的剩余度、提高符号平均信息量的基本途径有两个:①使序列中的各个符号尽可能地互相独立;②使序列中各个符号的出现概率尽可能地相等。
前者称为解除相关性,后者称为概率均匀化。
信源编码的一般问题可以表述如下:信源编码若某信源的输出为长度等于M的符号序列集合式中符号A为信源符号表,它包含着K个不同的符号,A={ɑk|k=1,…,K},这个信源至多可以输出K M个不同的符号序列。
记‖U‖=KM。
所谓对这个信源的输出信源编码进行编码,就是用一个新的符号表B的符号序列集合V来表示信源输出的符号序列集合U。
若V的各个序列的长度等于 N,即式中新的符号表B共含L个符号,B={b l|l=1,…,L}。
它总共可以编出L N个不同的码字。
类似地,记‖V‖=LN。
为了使信源的每个输出符号序列都能分配到一个独特的码字与之对应,至少应满足关系‖V‖=L N≥‖U‖=KM或者N/M≥log K/log L下面的几个编码定理,提供了解决这个矛盾的方法。
它们既能改善信息载荷效率,又能保证码字唯一可译。
离散无记忆信源的定长编码定理对于任意给定的ε>0,只要满足条件N/M≥(H(U)+ε)/log L那么,当M足够大时,上述编码几乎没有失真;反之,若这个条件不满足,就不可能实现无失真的编码。
Matlab函数实现哈夫曼编码算法

编写Matlab函数实现哈夫曼编码的算法一、设计目的和意义在当今信息化时代,数字信号充斥着各个角落。
在数字信号的处理和传输中,信源编码是首先遇到的问题,一个信源编码的好坏优劣直接影响到了后面的处理和传输。
如何无失真地编码,如何使编码的效率最高,成为了大家研究的对象。
哈夫曼编码就是其中的一种,哈夫曼编码是一种变长的编码方案。
它由最优二叉树既哈夫曼树得到编码,码元内容为到根结点的路径中与父结点的左右子树的标识。
所以哈夫曼在编码在数字通信中有着重要的意义。
可以根据信源符号的使用概率的高低来确定码元的长度。
既实现了信源的无失真地编码,又使得编码的效率最高。
二、设计原理哈夫曼编码(Huffman Coding)是一种编码方式,哈夫曼编码是可变字长编码(VLC)的一种。
uffman于1952年提出一种编码方法,该方法完全依据字符出现概率来构造异字头的平均长度最短的码字,有时称之为最佳编码,一般就叫作Huffman编码。
而哈夫曼编码的第一步工作就是构造哈夫曼树。
哈夫曼二叉树的构造方法原则如下,假设有n个权值,则构造出的哈夫曼树有n个叶子结点。
n 个权值分别设为w1、w2、…、wn,则哈夫曼树的构造规则为:(1) 将w1、w2、…,wn看成是有n 棵树的森林(每棵树仅有一个结点);(2) 在森林中选出两个根结点的权值最小的树合并,作为一棵新树的左、右子树,且新树的根结点权值为其左、右子树根结点权值之和;(3)从森林中删除选取的两棵树,并将新树加入森林;(4)重复(2)、(3)步,直到森林中只剩一棵树为止,该树即为所求得的哈夫曼树。
具体过程如下图1产所示:(例)图1 哈夫曼树构建过程哈夫曼树构造成功后,就可以根据哈夫曼树对信源符号进行哈夫曼编码。
具体过程为先找到要编码符号在哈夫曼树中的位置,然后求该叶子节点到根节点的路径,其中节点的左孩子路径标识为0,右孩子路径标识为1,最后的表示路径的01编码既为该符号的哈夫曼编码。
信息论实验报告(实验四、哈夫曼编码)

3、把这个合成概率看成是一个新组合符号地概率,重复上述做法直到最后只剩下两个符号概率为止;
4、完成以上概率顺序排列后,再反过来逐步向前进行编码,每一次有二个分支各赋予一个二进制码,可以对概率大的赋为零,概率小的赋为1;
5、从最后一级开始,向前返回得到各个信源符号所对应的码元序列,即相应的码字。
“1”,小的概率赋“0”。
(3)从最后一级开始,向前返回得到各个信源符号所对应的码元序列,即相应的码字。
(4)计算码字的平均码长得出最后的编码效率。
五、实验数据记录
六、实验结论与心得
通过本次实验,加强了对matlab程序的学习,进一步提高了我的编程能力。
如有侵权请联系告知删除,感谢你们的配合!
学生实验报告
院别
电子工程学院
课程名称
信息论与编码
班级
实验名称
实验四、哈夫曼编码
姓名
实验时间
学号
指导教师
成绩
报 告 内 容
一、实验目的和任务
1、理解信源编码的意义;
2、熟悉MATLAB程序设计;
3、掌握哈夫曼编码的方法及计算机实现;
4、对给定信源进行香农编码,并计算编码效率;
二、实验原理介绍
1、把信源符号按概率大小顺序排列,并设法按逆次序分配码字的长度;
三、实验设备介绍
1、计算机
2、编程软件MATLAB6.5以上
四、实验内容和步骤
对如下信源进行哈夫曼编码,并计算编码效率。
(1)计算该信源的信源熵,并对信源概率进行排序
(2)首先将出现概率最小的两个符号的概率相加合成一个概率,把这个合成概率与其他的概率进行组合,得到一个新的概率组合,重复上述做法,直到只剩下两个概率为止。之后再反过来逐步向前进行编码,每一次有两个分支各赋予一个二进制码。对大的概率赋
信息论与编码课程作业_huffman编码的matlab_实现

信息论与编码课程作业_huffman编码的matlab_实现信息论与编码课程作业——霍夫曼编码求信源熵和存储前后的信息量的变化一:设计目的:1、学习离散信源平均信息量的计算方法。
2、理解和掌握huffman 编码的基本原理,实现对信源符号的huffman 编码3、熟悉 Matlab 编程;二:设计原理和思路1.信源熵的计算:公式: 21()log a I a p = Matlab 实现:I=log2(1/p) 或I=-log2(p) 熵(平均自信息)的计算公式22111()log log qq i i i i i i H x p p p p ====-∑∑Matlab 实现:HX=sum(-x.*log2(x));或者h=h-x(i)*log2(x(i));2.霍夫曼编码原理;分为两步,首先是码树形成过程:对信源概率进行合并形成编码码树。
然后是码树回溯过程:在码树上分配编码码字并最终得到Huffman 编码。
1、码树形成过程:将信源概率按照从小到大顺序排序并建立相应的位置索引。
然后按上述规则进行信源合并,再对信源进行排序并建立新的位置索引,直到合并结束。
在这一过程中每一次都把排序后的信源概率存入矩阵p 中,位置索引存入矩阵m 中。
这样,由排序之后的概率矩阵 p 以及索引矩阵m 就可以恢复原概率矩阵P 了,从而保证了回溯过程能够进行下去。
2、码树回溯过程:在码树上分配编码码字并最终得到Huffman 编码。
从索引矩阵M 的末行开始回溯。
(1) 在p 的末行2元素位置填入0和1。
(2) 根据该行索引1位置指示,将索引1位置的编码(‘1’)填入上一行的第一、第二元素位置,并在它们之后分别添加‘0’和‘1’。
(3) 将索引不为‘1’的位置的编码值(‘0’)填入上一行的相应位置(第3 列)。
(4) 以m的倒数第二行开始向上,重复步骤(1) ~(3),直到计算至m的首行为止。
三:设计代码:>> clear all;format longdisp(strcat('信息论与编码课程作业——霍夫曼编码求信源熵和存储前后的信息量的变化',13));histgram=zeros(1,255);[c,map]=imread('C:\Documents and Settings\Administrator\桌面\infomation\lenna.bmp');x=rgb2gray(c);[a,b]=size(x);for i=1:afor j=1:bk=x(i,j);histgram(k)=histgram(k)+1;endendf=histgram/a/b;symbols=find(f~=0); %灰度值p=f(symbols); %概率L=length(p);pp=p;%霍夫曼编码m=zeros(L-1,L);for i=1:L-1[p,mark]=sort(p);m(L-i,1:L-i+1)=mark(1:L-i+1);p=[p(1)+p(2),p(3:L),1];endc=cell(L-1,L);c(1,1)={'0'};c(1,2)={'1'};for i=2:L-1;ind=find(m(i-1,:)==1);temp=char(c(i-1,ind));c(i,1)={[temp,'0']};c(i,2)={[temp,'1']};snc=find(m(i-1,:)~=1);for j=3:i+1;con=snc(j-2);c(i,j)=c(i-1,con);endendcodeL=[];averge_long=0;H1=0;disp(strcat('灰度值',32,32,32,'概率',32,32,32,32,32,32,32,32,32,'霍夫曼编码:'));for i=1:L;ind=find(m(L-1,:)==i);code=char(c(L-1,ind));codeLength(i)=length(code);averge_long=averge_long+pp(i)*codeLength(i);H1=H1+pp(i)*log2(1/pp(i));disp(strcat(32,num2str(symbols(i)),32,32,32,num2str(pp(i)),3 2,32, code));enddisp(strcat('信源熵=',num2str(H1),32,32,32,32,'平均码字长度=',num2str(averge_long),32,32,32,32,32,'压缩比=',num2str(8/averge_long)));四:设计运行结果:信息论与编码课程作业——霍夫曼编码求信源熵和存储前后的信息量的变化灰度值概率霍夫曼编码:30 1.5259e-005 101000111100001031 1.5259e-005 101000111100001136 1.5259e-005 101000111100000037 1.5259e-005 101000111100000139 6.1035e-005 1010001111000140 7.6294e-005 1110010101001041 6.1035e-005 0111010111011042 6.1035e-005 0111010111011143 9.1553e-005 1110010101001144 0.00018311 111011101010145 0.00021362 00111101101146 0.00022888 01110101111047 0.00024414 01110101111148 0.00039673 0011110110049 0.00048828 1010001110050 0.00065613 1110010101151 0.00090027 011101011052 0.00086975 001111011153 0.0013123 111001011054 0.0013733 111011101156 0.0018005 01110101057 0.0025177 11010001158 0.0036621 0111111059 0.0033722 0101111060 0.0046539 1100110161 0.0055847 1111010162 0.0061188 001001063 0.0080261 100111064 0.0075226 100001165 0.0083466 101010166 0.0088806 101111167 0.0092773 110011168 0.0095367 110101069 0.0086517 101101070 0.0084229 101011071 0.0075378 100010172 0.0071564 011011173 0.0061493 001001174 0.0056 1111011075 0.0053864 1110110076 0.0045319 1100011177 0.0043488 1011000178 0.0042114 1010111079 0.0039063 1000111180 0.0041199 1010100181 0.0035706 0110101182 0.0039368 1001011083 0.0037537 1000010084 0.003479 0110101086 0.0033417 0101101087 0.0032501 0100110088 0.0034027 0110000189 0.0031128 0011010090 0.0031433 0011110091 0.0036774 0111111192 0.0041046 1010011094 0.0038452 1000111095 0.004364 1011100096 0.0037842 1000110097 0.0037079 1000001198 0.0033722 0101111199 0.0040741 10100001 100 0.0040741 10100010 101 0.0038147 10001101 102 0.0040588 10011111 103 0.0041046 10100111 104 0.004364 10111001 105 0.0048218 11010111 106 0.0052185 11100100 107 0.0049591 11011010 108 0.005188 11100001 109 0.0047455 11010110 110 0.0052032 11100011 111 0.0054474 11110100 112 0.0057526 11111011 113 0.0065308 0100111 114 0.0079346 1001100 115 0.010223 1101111116 0.0095825 1101100 117 0.0089417 1100000 118 0.0086975 1011011 119 0.0081787 1010010 120 0.007782 1001001121 0.0066376 0101011 122 0.0059357 11111111 123 0.0056458 11110111 124 0.0051575 11100000 125 0.0052948 11101001 126 0.005188 11100010 127 0.0059814 0000001 128 0.0058594 11111101 129 0.0065613 0101010 130 0.0062561 0011011 131 0.006897 0110100132 0.0072479 0111011 133 0.0073242 0111110 134135 0.0075226 1000100 136 0.0077515 1001000138 0.008606 1011001139 0.0091095 1100100 140 0.012115 000010141 0.012115 000011142 0.012741 001110143 0.012329 001100144 0.010941 1111001145 0.010147 1101110146 0.0089417 1100001 147 0.0088043 1011101 148 0.0091095 1100101 149 0.010712 1110101150 0.011337 1111100151 0.010513 1110011152 0.012878 010000153 0.012268 001010154 0.013138 010100155 0.012238 001000156 0.012939 010001157 0.012115 000100158 0.012955 010010159 0.012207 000111160 0.011993 000001161 0.013916 011001162 0.012177 000110163 0.012299 001011164 0.0094604 1101001 165 0.0089874 1100010 166 0.0088501 1011110 167 0.0056915 11111010 168 0.0059357 0000000 169 0.0071716 0111001 170 0.0057678 11111100 171 0.0054016 11101111 172 0.0054169 11110001 173 0.0058746 11111110 174 0.0072937 0111100 175 0.0070953 0110110 176177 0.0061035 0001011 178 0.0054016 11110000 179 0.0053864 11101101 180 0.0046692 11010000182 0.0036774 10000000183 0.0033875 01100000184 0.0033264 01011000185 0.0031281 00110101186 0.0035706 01110000187 0.0033264 01011001188 0.0033569 01011011189 0.0036011 01110100190 0.0040436 10011110191 0.0034485 01100010192 0.0036774 10000001193 0.0032654 01001101194 0.0034485 01100011195 0.003006 00010100196 0.0033722 01011100197 0.0036774 10000010198 0.0042419 10110000199 0.0045166 11000110200 0.0041046 10101000201 0.0052643 11101000202 0.0050354 11011011203 0.0045319 11001100204 0.0039825 10011010205 0.0040588 10100000206 0.0039673 10010111207 0.0037537 10000101208 0.0033722 01011101209 0.0026703 111011100210 0.0022125 110100010211 0.0018768 101000110212 0.0015259 000101010213 0.0013428 1110010111214 0.0012665 1110010100215 0.0007782 0011110100216 0.00079346 0011110101217 0.00061035 10100011111218 0.00054932 10100011101219 0.00065613 11101110100220 0.00035095 111011101011 221 0.00033569 111001010101 222 0.00030518 101000111101 223 0.00021362 011101011100 224 0.00016785 1110111010100225 0.00019836 001111011010226 0.00015259 1110010101000227 0.00010681 0111010111010228 6.1035e-005 10100011110010230 3.0518e-005 101000111100110231 1.5259e-005 10100011110011110232 1.5259e-005 10100011110011111233 1.5259e-005 1010001111001110信源熵=7.2193 平均码字长度=7.2492 压缩比=1.1036五:设计新得体会:通过这学期对信息论和编码的学习,以及这次的设计,使我了解了很多东西,也使以前所学的知识得以巩固!,通过这次的设计,进一步学习了离散信源平均信息量、平均码长和压缩比的计算方法。
huffman编码用matlab的实现

一、实验目的
1、学习Matlab软件的使用和编程;
2、进一步深入理解Huffman编码算法的原理;
3、提高独立进行算法编程的能力.
二、实验环境
硬件:计算机
软件:Windows 2003和MATLAB编程环境。
三、实验内容
1、用Matlab实现Huffman编码算法程序;
end
end
for i=1:n
h(i,1:n)=c(1,n*(find(a(1,:)==i)-1)+1:find(a(1,:)==i)*n)
ll(i)=length(find(abs(h(i,:))~=32))
end
l=sum(p。*ll);
fprintf('\n huffman code:\n’);
(3)视此节点为新符号,其概率等于被合并(缩减)的两个概率之和,参与概率排队。
(4)重复(2)(3)两步骤,直至全部符号都被合并(缩减)到根.
(5)从根出发,对各分枝标记0和1.从根到叶的路径就给出了各个码字的编码和码长。
2、程序设计的原理
(1)程序的输入:以一维数组的形式输入要进行huffman编码的信源符号的概率,在运行该程序前,显示文字提示信息,提示所要输入的概率矢量;然后对输入的概率矢量进行合法性判断,原则为:如果概率矢量中存在小于0的项,则输入不合法,提示重新输入;如果概率矢量的求和大于1,则输入也不合法,提示重新输入。
2、通过这个实验,对huffman编码的具体实现原理了解的更加深刻,在实验的过程中也遇到了一些问题,通过查找资料和相关书籍得到了解决,通过此次试验,了解了Huffman编码的特点,能够运用Huffman编码的基本原理及编码算法的来设计与实现程序。收获颇多,为以后更进一步学习奠定了基础,总的来说,在完成该实验的过程中,学到了比较多的知识,包括使对一些matlab语句的掌握的更加熟练,完成一个算法必须要有一个整体的把握等等。
实验 Huffman编码(含matlab代码)

实验二Huffman编码一实验目的1 通过本实验实现信源编码——Huffman编码2 编写M文件实现,掌握Huffman编码方法二实验要求1 了解matlab中M文件的编辑、调试过程2 编写程序实现Huffman编码算法三实验步骤1 输入Huffman编码程序2 运行程序,按照提示输入相应信息,并记录输入信息,及运行结果。
注:观察结果方法:data(1).Code显示a1的编码,同理显示data(2).Code,a2的编码结果。
3 思考:该程序编出的Huffman码是否是最小码方差的码?为什么?四报告要求五附Huffman编码程序clearN=input('请输入信源符号的个数:') ;for i=1:N%data(1).name=input('请输入各信源符号的名称:');data(i).p=input('请输入各信源符号发生的概率:');endfor i=1:Npp(i)=data(i).p;data(i).imap=i; %各符号在编码过程中的指针data(i).Code=''; %各符号的编码结果endfor j = 1:N % N——信源符号的个数for i = 1:N - jif (pp(i) > pp(i + 1))fT = pp(i);pp(i) = pp(i + 1);pp(i + 1) = fT;for k = 1:Nif data(k).imap == idata(k).imap = i + 1;elseif data(k).imap == i + 1data(k).imap = i;endendendendendp=pp;%%%%%%%%%%%%%%%%%%%%% %// 计算哈夫曼编码表%// 开始编码for i=1:N-1for k = 1:Nif data(k).imap== idata(k).Code = strcat('1',data(k).Code);elseif (data(k).imap== i + 1)data(k).Code = strcat('0',data(k).Code);endendp(i + 1) = p(i + 1)+p(i);for k = 1:Nif (data(k).imap == i)data(k).imap = i + 1;endendfor j = i + 1:N-1if p(j) >p(j + 1)fT =p(j);p(j) = p(j + 1);p(j + 1) = fT;for k = 1:Nif (data(k).imap == j)data(k).imap = j + 1;elseif (data(k).imap == j + 1)data(k).imap = j;endendendendend。
哈夫曼编码Matlab实现

Matlab 中实现哈夫曼编译码:n=input('Please input the total number: ');hf=zeros(2*n-1,5);hq=[];for ki=1:nhf(ki,1)=ki;hf(ki,2)=input('Please input the frequency: ');hq=[hq,hf(ki,2)];endfor ki=n+1:2*n-1hf(ki,1)=ki;mhq1=min(hq);m=size(hq);m=m(:,2);k=1;while k<=m%del min1if hq(:,k)==mhq1hq=[hq(:,1:(k-1)) hq(:,(k+1):m)];m=m-1;breakelsek=k+1;endendk=1;while hf(k,2)~=mhq1|hf(k,5)==1%find min1 location k=k+1;endhf(k,5)=1;k1=k;mhq2=min(hq);k=1;while k<=m%del min2if hq(:,k)==mhq2hq=[hq(:,1:(k-1)) hq(:,(k+1):m)];m=m-1;breakelseendendk=1;while hf(k,2)~=mhq2|hf(k,5)==1%find min2 locationk=k+1;endhf(k,5)=1;k2=k;hf(ki,2)=mhq1+mhq2;hf(ki,3)=k1;hf(ki,4)=k2;hq=[hq hf(ki,2)];endclcchoose=input('Please choose what you want:\n1: Encoding\n2: Decoding\n3:.Exit\n');while choose==1|choose==2if choose==1a=input('Please input the letter you want to Encoding: ');k=1;while hf(k,2)~=ak=k+1;if k>=ndisplay('Error! You did not input this number.');breakendendif k>=nbreakendr=[];while hf(k,5)==1kc=n+1;while hf(kc,3)~=k&hf(kc,4)~=kkc=kc+1;endif hf(kc,3)==kelser=[1 r];endk=kc;endrelsea=input('Please input the metrix you want to Decoding: ');sa=size(a);sa=sa(:,2);k=2*n-1;while sa~=0if a(:,1)==0k=hf(k,3);elsek=hf(k,4);enda=a(:,2:sa);sa=sa-1;if k==0display('Error! The metrix you entered is a wrong one.');breakendendif k==0breakendr=hf(k,2);endchoose=input('Please choose what you want:\n1: Encoding\n2: Decoding\n3:.Exit\n');clc;endif choose~=1&choose~=2clc;end。
霍夫曼编码matlab

霍夫曼编码matlab在Matlab中实现霍夫曼编码可以通过以下步骤完成:1. 构建霍夫曼树,首先,你需要根据输入的数据统计每个符号出现的频率。
然后,使用这些频率构建霍夫曼树。
你可以使用Matlab中的数据结构来表示霍夫曼树,比如使用结构体或者类来表示节点。
2. 生成霍夫曼编码,一旦构建了霍夫曼树,你可以通过遍历树的方式生成每个符号对应的霍夫曼编码。
这可以通过递归或者迭代的方式实现。
3. 对数据进行编码和解码,使用生成的霍夫曼编码对输入的数据进行编码,然后再对编码后的数据进行解码。
这可以帮助你验证霍夫曼编码的正确性。
以下是一个简单的示例代码,用于在Matlab中实现霍夫曼编码: matlab.% 假设有一个包含符号频率的向量 freq 和对应符号的向量symbols.% 构建霍夫曼树。
huffTree = hufftree(freq);% 生成霍夫曼编码。
huffCodes = huffenco(symbols, huffTree);% 对数据进行编码。
data = [1 0 1 1 0 1 1 1]; % 你的输入数据。
encodedData = huffenco(data, huffCodes);% 对数据进行解码。
decodedData = huffmandeco(encodedData, huffTree);需要注意的是,以上代码仅为简单示例,实际应用中可能需要根据具体情况进行调整和完善。
同时,对于大规模数据的处理,也需要考虑到内存和性能方面的优化。
希望这个简单的示例能够帮助你在Matlab中实现霍夫曼编码。
哈夫曼编码matlab

哈夫曼编码matlab1. 引言哈夫曼编码是一种广泛应用于数据压缩领域的编码算法,它通过使用变长编码来表示不同符号,使得出现频率高的符号使用较短的编码,而出现频率低的符号使用较长的编码。
这种编码方式可以有效地降低数据的存储空间,提高数据传输效率。
在本文中,我们将使用Matlab编程语言来实现哈夫曼编码算法,并介绍其原理和实现步骤。
2. 哈夫曼编码原理哈夫曼编码的核心思想是根据符号的出现频率来构建一棵哈夫曼树,树中的叶子节点对应着不同的符号,而每个符号的编码则通过从根节点到达对应叶子节点的路径来表示。
构建哈夫曼树的过程可以分为以下几个步骤:2.1 统计符号频率首先,我们需要统计待编码数据中各个符号的出现频率。
在Matlab中,我们可以使用histc函数来实现这一步骤。
2.2 构建哈夫曼树根据频率统计结果,我们可以构建一棵哈夫曼树。
构建哈夫曼树的过程可以简化为以下几个步骤: 1. 将每个符号作为一个单独的节点插入到一个优先队列中。
2. 从优先队列中选择两个频率最低的节点,并合并它们为一个新节点。
该新节点的频率为两个被合并节点的频率之和。
3. 将新节点插入到优先队列中。
4. 重复步骤2和3,直到优先队列中只剩下一个节点为止。
该节点即为哈夫曼树的根节点。
2.3 生成编码表在构建好的哈夫曼树上,每个叶子节点都对应着一个符号,编码就是从根节点到达叶子节点的路径。
我们可以通过遍历哈夫曼树来生成每个符号的编码。
从根节点出发,如果经过左子树则编码为0,经过右子树则编码为1。
遍历到叶子节点时,记录下从根节点到达该叶子节点的路径,即为该符号的编码。
3. 哈夫曼编码的实现接下来,我们将使用Matlab来实现哈夫曼编码算法。
首先,我们需要读取待编码的数据。
3.1 读取数据使用Matlab提供的文件读取函数,我们可以方便地读取文本文件或二进制文件。
在本例中,我们以文本文件为例,假设我们需要对一段文本进行编码。
下面是读取文本文件的示例代码:fid = fopen('input.txt', 'r');textData = fscanf(fid, '%c');fclose(fid);3.2 统计符号频率读取数据后,我们需要统计各个符号的频率。
信息论实验用matlab实现哈夫曼码编译码

信息论与编码基础课程实验报告实验名称:Huffman码编译码实验姓名:学号:组别:专业:指导教师:班队:完成时间:成绩:Huffman码编译码实验一.实验目的和要求熟悉matlab软件编程环境及工具箱,掌握Huffman码编译码方法的基本步骤,利用matlab实现Huffman码的编译码。
二.试验内容和原理内容:利用matlab编程实现文本的二进制Huffman码的编译码。
任务:构造Huffman树。
原理:在各字符出现概率不均匀的情况下,根据这些概率构造一棵用于编码的Huffman树。
它用最短的二进制位表示出现概率最高的字符,而用较长的为表示出现概率低的字符,从而使平均码长缩短,并且保持编码的唯一可译性。
三.操作方法和实验步骤对一随机英文文本文件进行Huffman编译码仿真,给出各个字母的概率,码字,平均信息量,平均码长,编码效率以及编码序列输出。
(一)编码序列获取使用fopen函数读取.txt文本文件中的数据存储为字符串,使用length获取其长度,使用unique获取字符个数。
(二)获取编码概率矩阵使用strfind函数获取字符个数并计算各个符号的概率,根据哈夫曼编码原理依次获得各步骤中得到的概率,赋值给概率矩阵,使用find查找合并概率在的下标并存储到该列的最后一位,如有两个以上优先存储较大的那个下标。
(三)获取编码矩阵依据哈夫曼编码原理,根据获取的概率矩阵倒序编码。
最后一列直接编码0和1,取出最后一行中记录合并概率下标的数,由于该合并概率在上一列中肯定在最后两行,故优先编码,在字符串尾部加0和1;剩余编码直接平移,使用if 条件控制由于合并概率位置不同带来的平移方法不同。
(四)计算平均码长、自信息等使用公式计算平均码长、自信息、编码效率平均码长自信息编码效率(五)依据编码表编码由于是单符号信源,故使用strrep 字符替换函数直接替换(六)反向译码哈夫曼码是前向译码,遍历编码表,使用strncmpi 比较传输信息前x 个字符,如返回值为真直接译码,传输信息截取已经译码的部分,码字添加到译码信息中。
赫夫曼编码matlab实现

赫夫曼编码matlab实现赫夫曼编码(Huffman coding)是一种常用的数据压缩算法,通过将出现频率较高的字符用较短的编码表示,从而达到减少存储空间和传输数据量的目的。
本文将针对赫夫曼编码的实现进行详细介绍,并使用MATLAB语言进行具体实现。
文章将按照以下步骤逐一解释赫夫曼编码的实现过程,并给出MATLAB代码的编写。
1. 理解赫夫曼编码赫夫曼编码是一种前缀编码,即每个字符的编码都不是其他字符编码的前缀。
这种编码方式使得解码时不需要回溯,从而提高了效率。
赫夫曼编码的实现主要涉及两个步骤:构建哈夫曼树和生成编码表。
2. 构建哈夫曼树构建哈夫曼树是赫夫曼编码的第一步。
根据所需压缩的数据,统计每个字符出现的频率,并将频率作为节点权值构建一颗权值最小的二叉树。
构建哈夫曼树的步骤如下:a. 对于每个字符,统计其出现的频率。
b. 创建一个节点集合,将每个频率作为节点的权值,将所有字符节点加入集合。
c. 从节点集合中选取两个权值最小的节点合并,在新节点的左右子树上分别标记0和1。
d. 将新节点加入节点集合,重复上述步骤,直至节点集合中只剩下一个节点,此节点即为哈夫曼树的根节点。
3. 生成编码表生成编码表是赫夫曼编码的第二步。
在构建好哈夫曼树后,通过遍历哈夫曼树上的每个叶子节点,从根节点到叶子节点的路径上的左右分支分别表示0和1的编码,将每个字符对应的编码存储在编码表中。
4. 实现赫夫曼编码的MATLAB代码使用MATLAB语言可以方便地实现赫夫曼编码算法。
以下是一个简单的赫夫曼编码的MATLAB代码示例:function [codes, tree] = huffman_encode(text)freq = histcounts(text);chars = unique(text);nodes = cell(length(chars), 1);for i = 1:length(chars)nodes{i} = struct('Symbol', chars(i), 'Frequency', freq(i), 'Code', '');endwhile length(nodes) > 1[value, idx] = sort(cellfun(@(x) x.Frequency, nodes));node1 = nodes{idx(1)};node2 = nodes{idx(2)};newNode = struct('Symbol', '', 'Frequency', node1.Frequency + node2.Frequency, 'Code', '');newNode.Left = node1;newNode.Right = node2;nodes(idx(2)) = [];nodes(idx(1)) = [];nodes{end + 1} = newNode;endtree = nodes{1};assign_codes(tree, '');for i = 1:length(chars)idx = find(cellfun(@(x) strcmp(x.Symbol, chars(i)), nodes));codes{i, 1} = chars(i);codes{i, 2} = nodes{idx}.Code;endendfunction assign_codes(node, code)if ~isempty(node.Left)assign_codes(node.Left, strcat(code, '0'));endif ~isempty(node.Right)assign_codes(node.Right, strcat(code, '1'));endif isempty(node.Left) && isempty(node.Right) node.Code = code;endend5. 示例测试可以使用一段文本进行测试,例如:text = 'this is an example for huffman encoding'; codes = huffman_encode(text);disp(codes);运行结果将输出每个字符的编码,如:' ' '1101''a' '111''c' '1001''d' '01001''e' '11''f' '0101''g' '00100''h' '000''i' '101''l' '00111''m' '01100''n' '1000''o' '00110''p' '00101''r' '01000''s' '10001''t' '0101''x' '01101'通过以上步骤,我们可以成功地实现赫夫曼编码的MATLAB实现。
基于matlab对哈夫曼编码的实现

在MATLAB中实现哈夫曼编码需要先建立哈夫曼树,然后基于这颗哈夫曼树生成对应的哈夫曼编码。
以下是使用MATLAB实现哈夫曼编码的简单步骤:
假设你有一个要编码的符号集合symSet和这些符号的概率集合probSet。
1.计算频率和概率: 首先,我们需要计算每个符号的频率和概率。
freq = histc(symSet, symSet); % 计算频率
prob = freq / sum(freq); % 计算概率
2.构建哈夫曼树: 使用huffTree函数构建哈夫曼树。
[huffTree, huffCodes] = huffTree(prob);
3.生成哈夫曼编码: 使用huffmanenco函数生成哈夫曼编码。
huffmanCodes = huffmanenco(symSet, huffTree);
4.测试: 使用生成的哈夫曼编码对原始数据进行编码和解码。
originalData = symSet(randperm(length(symSet), 1000)); % 随机生成1000个原始数据
encodedData = huffmanenco(originalData, huffTree); % 对原始数据进行编码
decodedData = huffDeco(encodedData, huffCodes); % 解码编码后的数据
5.比较解码后的数据与原始数据: 检查解码后的数据是否与原始数据匹配。
以上是MATLAB实现哈夫曼编码的基本步骤,具体的代码可能需要根据你的数据和需要进行一些调整。
matlab 哈夫曼编码

matlab 哈夫曼编码哈夫曼编码是一种可变长度的编码方式,它可以将一组可能不等概率出现的字符序列压缩成一个二进制编码的表示方式,以达到数据压缩的目的。
在哈夫曼编码中,出现频率越高的字符所对应的编码越短,反之越长。
需要注意的是,将字符压缩成的二进制编码只能满足单词不重复的情况下才能唯一的解码出来,因此在实际应用中还需要对编码进行强制分界,以保证无二义性。
在Matlab中进行哈夫曼编码可以使用built-in函数'huffmandict'和'huffmanenco'来完成。
其中'huffmandict'函数根据字符和频率信息来生成哈夫曼字典,'huffmanenco'函数将读入的原始数据运用哈夫曼编码压缩成一个码字,也可以使用'huffmandeco'函数将压缩后的数据解码。
下面我给出一个简单的演示,解释如何使用Matlab实现哈夫曼编码过程。
假设我们要压缩的原始数据如下:matlabcharList = ['a', 'b', 'c', 'd', 'e', 'f'];probList = [0.2, 0.15, 0.1, 0.12, 0.3, 0.13];data = ['a', 'c', 'b', 'a', 'e', 'b', 'f', 'e', 'f', 'c', 'c', 'a', 'd', 'a', 'b', 'e'];首先我们需要生成一个哈夫曼字典:matlabhuffDictionary = huffmandict(charList, probList);这里的'huffmandict'函数通过输入字符符号和对应概率的向量,生成一个哈夫曼字典。
Huffman编码(哈夫曼编码)的Matlab实现

clear 【1 】all fprintf('Reading data...')data=imread('cameraman.tif');data=uint8(data);%读入数据,并将数据限制为uint8 fprintf('Done!\n')%编码紧缩fprintf('compressing data...');[zipped,info]=norm2huff(data);fprintf('Done!\n')%解紧缩fprintf('compressing data...');unzipped=huff2norm(zipped,info);fprintf('Done!\n')%测试是否无掉真isOK=isequal(data(:),unzipped(:))%显示紧缩后果whos datazippedunzippedfunction [zipped,info]=norm2huff(vector)if~isa(vector,'uint8'),error('input argument must be a uint8 vector') endvector=vector(:)';%将输入向量转换为行向量f=frequency(vector);%盘算个元素消失的概率simbols=find(f~=0);f=f(simbols);%将元素按消失的概率分列[f,sortindex]=sot(f);simbols=simbols(sortindex);%产生码字 generate the codeword as the 52 bits of a doublelen=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 datainordertohavetwonodeswithlowerfrequencyasfirst to[f,sortindex]=sort(f);simbols_index=simbols_index(sortindex);end%对应响应的元素与码字codeword=cell(256:1);codeword(simbols)=codeword_tmp;%盘算总的字符串长度len=0;for index=1:length(vector),len=len+length(codeword{double(vector(index))+1}); end%产生01序列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%假如须要,加零len=length(string);pad=8-mod(len,8);if pad>0,string=[string uint8(zeros(1,pad))];end%保管现实有效的码字codeword=codeword(simbols);codelen=zeros(size(codeword));weights=2.^(0:23);maxcodelen=0;for index 1:length(codeword),len=length(codeword{index});if len>maxcodelen,maxcodelen=len;endif len>0,code=sum(weights(codeword{index}==1)); code=bitset(code,len+1);codeword{index}=code;codelen(index)=len;endendcodeword=[codeword{:}]%盘算紧缩后的向量cols=length(string)/8;string=reshape(string,8,cols);weights=2.^(0:7);zipped=uint8(weights*double(string));%存储一个稀少矩阵huffcodes=sparse(1,1);% init sparse matrixfor index=1:numel(codeword),huffcodes(codeword(index),1)=simbols(index); end%产生信息构造体info.pad=pad;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}];endfunction vector=huff2norm(zipped,info)%HUFF2NORM Huffman 解码器%HUFF2NORM(X,INFO)依据信息体构造 info 返回向量 zipped 的解码成果%%矩阵参数以X(:)情势输入if~isa(zipped,'uint8'),error('input argument must be a uint8 vector')end%产生01序列len=length(zipped);string=repmat(uint8(0),1,len.*8);bitindex=1:8;for index+1:len,string(bitindex+8.*(index-1))=uint8(bitget(zipped(index),bitindex)); end%调剂字符串string=logical(string(:)');% remove 0 paddinglen=length(string);%解码weights=2.^(0:51);vector=repmat(uint8(0),1,info,length);vectorindex=1;codeindex=1;code=0;for index=1:len,code=bitset(code,codeindex,string(index));]codeindex=codeindex+1;byte=decode(bitset(code,codeindex),info);if byte>0,%vector(vectorindex)=byte-1;codeindex=1;code=0;vectorindex=vectorindex+1;endendfunction byte=decode(code,info)byte=info.huffcodes(code);function f=frequency(vector)%FREQUENCY 盘算元素消失概率if~isa(vector,'uint8'),error('input argument must be a uint8 vector') endf=repmat(0,1,256);%扫描向量len=length(vector);for index=0:256,%f(index+1)=sum(vector==uint8(index)); end%归一化f=f./len;。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
信息论与编码基础课程实验报告实验名称:Huffman码编译码实验姓名:学号:组别:专业:指导教师:班队:完成时间:成绩:Huffman码编译码实验一.实验目的和要求熟悉matlab软件编程环境及工具箱,掌握Huffman码编译码方法的基本步骤,利用matlab实现Huffman码的编译码。
二.试验内容和原理内容:利用matlab编程实现文本的二进制Huffman码的编译码。
任务:构造Huffman树。
原理:在各字符出现概率不均匀的情况下,根据这些概率构造一棵用于编码的Huffman树。
它用最短的二进制位表示出现概率最高的字符,而用较长的为表示出现概率低的字符,从而使平均码长缩短,并且保持编码的唯一可译性。
三.操作方法和实验步骤对一随机英文文本文件进行Huffman编译码仿真,给出各个字母的概率,码字,平均信息量,平均码长,编码效率以及编码序列输出。
(一)编码序列获取使用fopen函数读取.txt文本文件中的数据存储为字符串,使用length获取其长度,使用unique获取字符个数。
(二)获取编码概率矩阵使用strfind函数获取字符个数并计算各个符号的概率,根据哈夫曼编码原理依次获得各步骤中得到的概率,赋值给概率矩阵,使用find查找合并概率在的下标并存储到该列的最后一位,如有两个以上优先存储较大的那个下标。
(三)获取编码矩阵依据哈夫曼编码原理,根据获取的概率矩阵倒序编码。
最后一列直接编码0和1,取出最后一行中记录合并概率下标的数,由于该合并概率在上一列中肯定在最后两行,故优先编码,在字符串尾部加0和1;剩余编码直接平移,使用if 条件控制由于合并概率位置不同带来的平移方法不同。
(四)计算平均码长、自信息等使用公式计算平均码长、自信息、编码效率平均码长自信息编码效率(五)依据编码表编码由于是单符号信源,故使用strrep 字符替换函数直接替换(六)反向译码哈夫曼码是前向译码,遍历编码表,使用strncmpi 比较传输信息前x 个字符,如返回值为真直接译码,传输信息截取已经译码的部分,码字添加到译码信息中。
四.实验数据记录和处理close all ;clear all ;clc;%关闭所有图形窗口,清楚工作空间所有变量,清除命令行%%%%%%%%%文件数据读取%%%%%%%%%%code=fopen( '\test02.txt'); %打开文件mail=fscanf(code, '%c'); %读取文件的数据,并将数据存入矩阵,输出字符串 mms=unique(mail); %unique 函数去除重复字符,计算出字符串的种类 % disp(xulie); %输出文档中包含的字符n=length(mms); %n 为需要编码元素个数,length 函数获取字符串长度 for i=1:ncount(i)=length(strfind(mail,mms(i)));rLS 2log /)(H =η符号码元/l p L q1i i i ∑==码元/bit p log p H(S)q1i i 2i ∑=-=%统计各字符个数复制给count(i),strfind为字符查找函数,返回值为查找个数endP=count./sum(count); %计算各字符的概率for i=1:nPP{i,1}=mms(i);PP{i,2}=P(i);endPP=sortrows(PP,-2);T=sort(P,'descend'); %降序排列P,为减少对P的影响,复制排序后的P为T %%%%%%%%%%%%%编码准备(概率矩阵生成)%%%%%%%%%%B=zeros(n,n-1);%B为空的编码概率矩阵,第一列n个,最后一列2个故用n*(n-1)for i=1:nB(i,1)=T(i); %生成编码表的第一列(即为复制T)endr=B(i,1)+B(i-1,1); %最后两个元素相加T(n-1)=r; %将两个元素相加之和赋给倒数第二个数T(n)=0; %最后一个数置零T=sort(T,'descend'); %对第一次相加后的T排序t=n-1; %置数t,用来表示当前概率序列中不为零的个数for j=2:n-1 %生成编码表的其他各列(从第二列开始)for i=1:tB(i,j)=T(i); %将上一次处理后的概率序列复制给下一列endK=find(T==r);%找到r在T中的位置并置给K(K是向量,记录的是位置信息所在列数)B(n,j)=K(1);%从第二列开始,每列的最后一个元素记录上一列相加后的数在该列的位置,取概率之首可以减少码长方差r=(B(t-1,j)+B(t,j)); %最后(小)两个概率相加T(t-1)=r;T(t)=0; %重复动作,相加最小两数,并将后一位置零T=sort(T,'descend'); %对T再排序t=t-1; %每次处理后t自减(需处理的概率自减)end%%%%%%%%%%%%%%编码部分%%%%%%%%%%%%%%%m=n-1; %为简便引入m,表示码字最长可能,也是列数等huffman{1,m}='0';huffman{2,m}='1';t=2; %t是实时本列的概率元素个数,也表示下一列第一个合并概率的行数for j=m:-1:2 %j是实时的列数k=B(n,j);huffman{t,j-1}=strcat(huffman{k,j},'0'); %先解决上一列最后两个huffman{t+1,j-1}=strcat(huffman{k,j},'1');%strcat做字符串拼接if k==1 %如果合成的概率排在首位,那就斜着复制for i=1:t-1 %i表示列数,z表示字符顺序huffman{i,j-1}=huffman{i+1,j};endelseif k==t %如果合成的概率排在末位,那就平着复制for i=1:t-1huffman{i,j-1}=huffman{i,j};endelse%如果合成的概率排在中间,上半部分平着,下半部分斜着for i=1:k-1 %上半部分平移huffman{i,j-1}=huffman{i,j};endfor i=k:t-1 %下半部分斜着移过去huffman{i,j-1}=huffman{i+1,j};endendt=t+1;endhuffman%%%%%%%%%输出结果%%%%%%%%%%%%%%disp('编码结果')for i=1:nPP{i,3}=huffman{i,1};endPP=sortrows(PP,-2); %sortrows对字符依据概率大小排序disp(PP); %输出for i=1:nlong=length(PP{i,3});L(i)=long;enddisp('平均码字长度');len=sum(L.*P);disp(len); %平均码长lenH1=log2(P);disp('平均信息量');H=-P*(H1'); %平均信息量Hdisp(H);disp('编码效率');Pp=H/len; %编码效率Ppdisp(Pp)%%%%%%%%%%%%%%%编码部分%%%%%%%%%%%%%%%%%tran=strrep(mail,char(PP{1,1}),char(PP{1,3})); %strrep为字符替换函数for i=2:ntran=strrep(tran,char(PP{i,1}),char(PP{i,3}));enddisp('编码输出')disp(tran);%%%%%%%%%%%%%%%%译码部分%%%%%%%%%%%%%%%%%%retran='';left=tran;%比较传输字符的前几位与码字,如果找到将译码部分添加到retran,剩余数据截取存储到leftwhile(length(left)>0)for i=1:nif (strncmpi(left,char(PP{i,3}),length(PP{i,3})))retran=strcat(retran,char(PP{i,1}));left=left((length(PP{i,3})+1):length(left));endendenddisp('译码输出')disp(retran);disp('原始信息')disp(mail);if(strcmp(mail,retran))disp('译码成功');end五.实验结果与分析1.(1)测试文件test01.txt中存储字符串(2)查看概率矩阵B(3)查看编码矩阵huffman (4)查看运行结果,编译码无误2.(1)测试文件test02.txt中存储字符串(2)查看概率矩阵B(3)查看编码矩阵huffman(4)查看运行结果,编译码无误3.结果分析可知,程序已完成了Huffman编码的功能,但结果并不唯一,验证了霍夫曼编码是不唯一的。
因为:信源符号合并中遇到最小概率相同的情况时可任意选择来做合并;在码树分配编码码字的时候1 和0 的位置可以是任意的。
编码本码字不同并不影响文本传输,六.讨论和心得思考:1、如何对文本进行概率统计?答:读取文本数据存储在字符串中,使用unique去除重复字符得到字符集合,遍历字符串,得到各个字符的个数。
2、如何分析编码性能?答:平均码长、编码效率都是直接反映编码性能的参数。
哈夫曼码的平均码长比相同信源的香农码和费诺码短;编码效率为编码后信息传输速率与最大可能信息传输速率的比值。
3、试分析Huffman码在使用中的复杂性、并行性的相应改进。
(选答)答:哈夫曼码在编码过程中需要重复排序,编码过程比香农编码和费诺编码复杂,使用过程中不等长编码和等长编码在译码过程中更复杂。