哈夫曼编码的分析与实现.docx
《哈夫曼编码的分析与实现.docx》由会员分享,可在线阅读,更多相关《哈夫曼编码的分析与实现.docx(9页珍藏版)》请在冰豆网上搜索。
哈夫曼编码的分析与实现
x电气与电子信息工程学院
信息理论与编码课程设计报告
设计题目:
哈夫曼编码的分析与实现
专业班级:
电x1
学生姓名:
x
学号:
xx
指导教师:
xx
设计时间:
2012.11.19-2011.11.30
教师评语:
成绩评阅教师日期
1、设计的作用、目的
《信息论与编码》是一门理论与实践密切结合的课程,课程设计是其实践性教学环节之一,同时也是对课堂所学理论知识的巩固和补充。
其主要目的是加深对理论知识的理解,掌握查阅有关资料的技能,提高实践技能,培养独立分析问题、解决问题及实际应用的能力。
通过完成具体编码算法的程序设计和调试工作,提高编程能力,深刻理解信源编码、信道编译码的基本思想和目的,掌握编码的基本原理与编码过程,增强逻辑思维能力,培养和提高自学能力以及综合运用所学理论知识去分析解决实际问题的能力,逐步熟悉开展科学实践的程序和方法。
二、设计任务及要求
2.1理解无失真信源编码的理论基础,掌握无失真信源编码的基本方法;
2.2根据哈夫曼编码算法,考虑一个有多种可能符号(各种符号发生的概不同)的信源,得到哈夫曼编码和码树;
2.3掌握哈夫曼编码的优缺点;
2.4能够使用MATLAB或其他语言进行编程,编写的函数要有通用性要
理解每个函数的具体意义和适用范围,对主要函数的功能和参数做详要求程序
输出显示所有的码字,平均码长,编码效率。
三、设计内容
一个有8个符号的信源X,各个符号出现的概率为:
进行哈夫曼编码,并计算平均码长、编码效率、冗余度。
四、设计原理
4.1哈夫曼编码步骤
(1)将信源消息符号按其出现的概率大小依次排列P1≥P2≥···≥Pn。
(2)取两个概率最小的字母分别配以0和1两个码元,并将这两个概率相
加作为一个新的字母的概率,与未分配的二进制符号的字母重新排队。
(3)对重排后的两个概率最小符号重复步骤
(2)的过程。
(4)不断继续上述过程,直到最后两个符号配以0和1为止。
(5)从最后一级开始,向前返回得到各个信源符号所对应的码元序列,即
相应的码字
4.2哈夫曼编码特点
(1)凡是能载荷一定的信息量,且码字的平均长度最短,可分离的变长的码字集合称为最佳变长码。
为此必须将概率大的信息符号编以短的码字,概率小符号编以长的码字,使得平均码字最短,为最佳编码方法。
哈弗曼码是用用概率匹配的方法进行信源编码。
它有两个显著特点:
一是哈弗曼码的编码方法保证了概率大的符号对应于短吗,概率小的符号度对应于长码,充分利用了短码;二是缩减了心愿的最后两个码字总是最后一位不同,从而保证了哈弗曼码是即时码哈弗曼变长码的效率是相当高的,它可以单个信源符号编码或用L较小的信源序列编码,对编码的设计来说也是简单得多。
但是应当注,要达到很高的效率仍然需要按长序列计算,这样才能使平均码字长度降低。
哈夫曼编码方法得到的码并非是唯一的,造成并非唯一的原因是:
首先,每次对信源缩减时,赋予信源最后两个概率最小的符号,用0和1可以任意的,所以可以得到不同的哈夫曼码,但不会影响码字的长度。
其次:
对信源进行缩减时两个概率最小的符号合并后的概率与其他信源符号的概率相同时,这两者在缩减信源中进行概率排序,其位置放置次序是可以任意的,故会得到不同的哈夫曼码此时将影响码字的长度,一般将合并的概率放在上面,这样可以获得较小的码方差。
对于多进制哈夫曼编码,为了提高编码效率,就要使长码的符号数量尽量少、概率尽量小,所以信源符号数最好满足
其中r为进制数,n为缩减的次数。
例如,要进行三进制编码,那么最好信源有7个符号,第1次合并后减少2个成为5个,第2次合并后又减少2个成为3个,这样给每一步赋予三进制符号就没有浪费了。
但如果信源只有6个符号时,为了尽量减少最长码的数量,则应该在第1次合并时添置概率为零的虚拟符号1个,事实上只合并2个概率最小的符号,后面每次合并三个,就可以使得最长码的符号数量最少,也就是长码的概率最小,从而得到最高的编码效率。
(2)哈夫曼编码在实际中已有应用,但它仍然存在一些分组码所具有的缺点。
例如概率特性必须得到精确地测定,它若略有变化,还需要换码表,以及对于二元信源,常需要多个符号合起来编码,才能取得好的效果,但当合并的符号数不大时,编码效率提高不多,尤其对于相关信源,不能令人满意,而合并的符号数增大时,码表中的码字数很多,设备将越来越复杂。
当容量设定后,随着时间的增长,存储器溢出和取空的的概率都将增。
当T很大时,几乎一定会溢出或损失;由此可见,对于无线长的信息,很难采用变长码而不出现错误。
一般来说,变长码只适用于有限码的传输;即送出一段信息后,信源就停止输出,例如传真机送出一张纸上的信息后停止。
对于长信息在实际使用时可把长信息分段送出,也可通过检测存储器的状态调节信源输出即发现存储器将要溢出就停止信源输出;发现存储器将要被取空就在信道上插上空闲标志,或加快信源输出。
变长码可以无失真的译码,这是理想情况。
如果这种变长码是由信道输入的,一个码子前面有一个码元错了,就可能误认为是另一个码字而断点,结果后面一系列的码字也会译错,这常称为差错的扩散。
当然也可以采用某些措施,使码元错了一段以后,能恢复正常的码字分离和译码,这一般要求在传输过程中差错很少,或者加纠错用的监督码位,但是这样一来又增加了信息率。
此外,当信源有记忆时,用单个符号编码不可能是编码效率接近于1,因此信息率只能接近一维熵H1,而H一定小于H1。
此时仍需要多个符号一起编码,才能提高编码效率。
但导致码表长,存储器多。
五、设计步骤
5.1以框图形式画出哈夫曼编码过程
哈夫曼编码过程
哈夫曼码树
5.2计算平均码长、编码效率、冗余度。
在变字长编码时每个符号的平均码长为:
=0.3×2+0.2×2+0.18×2+0.1×4+0.08×4+0.07×4+0.04×5+0.03×5
=2.71码元/符号
平均信息量就是信息熵(entropy)为:
=-{0.3×log(0.3)+0.2×log(0.2)+0.18×log(0.18)+0.08×log
(0.08)+0.07×log(0.07)+0.04×log(0.04)+0.03×log(0.03)}
=2.66bit/符号
编码效率为:
冗余度为:
六、哈夫曼编码的MATLAB实现
6.1MATLAB编程
p=input('请输入数据:
')%提示输入界面
n=length(p);
fori=1:
n
ifp(i)<0
fprintf('\n提示:
概率值不能小于0!
\n');
p=input('请重新输入数据:
')
end
end
ifabs(sum(p))>1
fprintf('\n哈弗曼码中概率总和不能大于1!
\n');
p=input('请重新输入数据:
')
end
q=p;
a=zeros(n-1,n);%生成一个n-1行n列的数组
fori=1:
n-1
[q,l]=sort(q)
a(i,:
)=[l(1:
n-i+1),zeros(1,i-1)]
q=[q
(1)+q
(2),q(3:
n),1];
end
fori=1:
n-1
c(i,1:
n*n)=blanks(n*n);
end
c(n-1,n)='0';c(n-1,2*n)='1';
fori=2:
n-1
c(n-i,1:
n-1)=c(n-i+1,n*(find(a(n-i+1,:
)==1))-(n-2):
n*(find(a(n-i+1,:
)==1)))
c(n-i,n)='0'%根据之前的规则,在分支的第一个元素最后补0
c(n-i,n+1:
2*n-1)=c(n-i,1:
n-1)
c(n-i,2*n)='1'%根据之前的规则,在分支的第一个元素最后补1
forj=1:
i-1
c(n-i,(j+1)*n+1:
(j+2)*n)=c(n-i+1,n*(find(a(n-i+1,:
)==j+1)-1)+1:
n*find(a(n-i+1,:
)==j+1))
end
end%完成huffman码字的分配
fori=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))%计算每一个huffman编码的长度
end
l=sum(p.*ll);%计算平均码长
fprintf('\nHuffman编码结果为:
\n');h
fprintf('\n编码的平均码长为:
\n');l
hh=sum(p.*(-log2(p)));%计算信源熵
fprintf('\n信源熵为:
\n');hh
fprintf('\n编码效率为:
\n');t=hh/l%计算编码效率
6.2运行结果及分析
运行结果分析:
完成编写设计后,在MATLAB中运行并验证结果,首先输入概率向量:
>>p=[0.30,0.20,0.18,0.10,0.08,0.07,0.04,0.03];再调用编写的Huffman函数:
>>[HuffmanTree,HuffmanCode,SumCode,Entropy]=Huffman(p)回车即可得到执行的结果,编码长度为L=2.7100,H(X)=2.6606,结果如上图所得的结果与实际预测的理论结果L=2.71,H(X)=2.66在误差允许范围内一致。
七、体会及建议
通过本次课程设计,让我对哈弗曼编码以及MATLAB有了更深的理解和操作能力。
开始针对题目进行分析,将所涉及的知识点,及相关函数做了分析,大体能够把握整体的设计流程及思路。
再通过查阅相关资料,使自己的知识也更加丰富了,懂得了哈弗曼编码的原理。
首先对给题目进行了笔算,进行哈弗曼编码,求出平均码长,编码效率,开始时不是很顺利,以前学的忘了大半啊,经过复习课本的内容,掌握原理后顺利求出结果。
然后是利用MATLAB编写程序,在网上查阅了一些资料,又借了几本MATLAB的书籍,仔细研究后得出了程序,有一部分也是在网上下的,但是在运行时还是出错了,之后又经过几次的修改,终于得出了结果,可是和自己计算的码却是相反的,而其它结果却是相同,让我疑惑了,我又仔细想了想了,原因应该出现在编码的时候,在编码过程中如果0和1赋值相反的话,就会出现这种情况,但是两种的码字应该都是正确的。
过而能改,善莫大焉。
在课程设计过程中,我们不断发现错误,不断改正,不断领悟,不断获龋最终的检测调试环节,本身就是在践行“过而能改,善莫大焉”的知行观。
这次课程设计终于顺利完成了,在设计中遇到了很多问题,最后在老师的指导下,终于游逆而解。
在今后社会的发展和学习实践过程中,一定要不懈努力,不能遇到问题就想到要退缩,一定要不厌其烦的发现问题所在,然后一一进行解决,只有这样,才能成功的做成想做的事,才能在今后的道路上劈荆斩棘,而不是知难而退,那样永远不可能收获成功,收获喜悦,也永远不可能得到社会及他人对你的认可!
其次在这两周的课程设计中,不仅让我对以前学过的知识有又记了起来,而且对其更是有了深层次的理解。
再动手方面也有很大的提高,对计算机的操作也比以前强了很多。
也体会到了团队合作的力量。
我想说,设计确实有些辛苦,但苦中也有乐,在如今单一的理论学习中,很少有机会能有实践的机会,但我们可以,而且设计也是一个团队的任务,大家一起工作可以让我们有说有笑,相互帮助,配合默契,多少人间欢乐在这里洒下,大学里一年的相处还赶不上这十来天的合作,我感觉我和同学们之间的距离更加近了;我想说,确实很累,但当我们看到自己所做的成果时,心中也不免产生兴奋;我们同样可以为社会作出我们应该做的一切,这有什么不好?
我们不断的反问自己。
但是也许有人不喜欢这类的工作,也许有人认为设计的工作有些枯燥,但我们认为无论干什么,只要人生活的有意义就可。
社会需要我们,我们也可以为社会而工作。
既然如此,那还有什么必要失落呢?
于是我们决定沿着自己的路,执着的走下去。
最后通过这次课程设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为社会服务,在设计过程中虽然遇到了一些问题,但经过一次又一次的思考,一遍又一遍的检查终于找出了原因所在,也暴露出了前期我在这方面的知识欠缺和经验不足。
实践出真知,通过亲自动手制作,使我们掌握的知识不再是纸上谈兵从而提高自己的实际动手能力和独立思考的能力。
在设计的过程中遇到问题,可以说得是困难重重,这毕竟第一次做的,难免会遇到过各种各样的问题,同时在设计的过程中发现了自己的不足之处,对以前所学过的知识理解得不够深刻,掌握得不够牢固。
转眼间两周的课程设计就结束了,在这过程中我们每个人都收获颇丰,在此期间也得到了老师和同学的热心帮助,在这里忠心的感谢,希望学校以后可以有更多的实践课题,让我们不仅可以掌握理论的知识,也可以让我们增强动手的能力。
八、参考文献
[1]曹雪虹,张宗橙.信息论与编码(第二版).北京:
清华大学出版社.2009
[2]吕锋,王虹,刘皓春,苏扬.信息论与编码.北京:
人民邮电出版社.2004
[3]樊昌信,曹丽娜.通信原理(第六版).北京:
国防工业出版社.2006
[4]罗建军.MATLAB教程.电子工业出版社.2007
[5]曹弋.MATLAB教程及实训.机械工业出版社.2008
[6]苏金明,阮沈勇.MATLAB适用教程(第二版).电子工业出版社.2008