二元霍夫曼编码 - 信息论与编码实验报告

时间:2024.4.26

计算机与信息工程学院综合性实验报告

专业:通信工程        年级/班级:20##级      20##—20##学年第一学期

一、实验目的

根据霍夫曼编码的原理,用MATLAB设计进行霍夫曼编码的程序,并得出正确的结果。

二、实验仪器或设备

1、一台计算机。

2、MATLAB r2013a。

三、二元霍夫曼编码原理

1、将信源消息符号按其出现的概率大小依次排列,p1>p2>>pq

2、取两个概率最小的字母分别配以0和1两个码元,并将这两个概率相加作为一个新字母的概率,从而得到只包含q-1个符号的新信源S1。

3、对重排后的缩减信源S1重新以递减次序排序,两个概率最小符号重复步骤(2)的过程。

4、不断继续上述过程,直到最后两个符号配以0和1为止。

5、从最后一级开始,向前返回得到各个信源符号所对应的码元序列,即相应的码字。

四、霍夫曼编码实现程序

function [outnum]=lml_huffman(a)

%主程序,输入一组概率,输出此组概率的霍夫曼编码

%a:一组概率值,如a=[0.2 0.3 0.1 0.4]等

%outnum:输出的霍夫曼码,以cell中的字符数组表示

if sum(a)~=1

    warning('输入概率之和不为“1”,但程序仍将继续运行')

end

[cho,sequ,i,l]=probality(a);

global lmlcode              %用于输出霍夫曼码,定义为cell型

global cellnum              %用于编码的累加计算

cellnum=1;

lmlcode=cell(l,1);

j=1;                              %第一部分

add_num=char;

[l_add]=addnum(add_num,i,j,l);

[output,m]=disgress(sequ,i,j,l,l_add);

dealnum(output,m);     %在全局变量中输出霍夫曼码

j=2;                             %第二部分

[l_add]=addnum(add_num,i,j,l);

[output,n]=disgress(sequ,i,j,l,l_add);

dealnum(output,n);

[outnum]=comset(lmlcode,cho(1,:));%将概率和编码进行关联

function [output]=addnum(input,i,j,l)

%对概率矩阵中每一行最后两个不为0的数进行编码,即在某个编码后添加0,1或空

%输出:

%      input:输入的某个未完成的编码

%     (i,j):当前检索目标在sequ矩阵中的位置

%      l:sequ矩阵的列数

%PS: sequ矩阵在此函数中未用到

%PS:此函数为编码第一步

if j==(l-i)

    output=[input '0'];

else if j==(l-i+1)

        output=[input '1'];

    else

        output=input;

    end

end

function [ecode]=comset(code,pro)

%将概率和编码进行关联

%code:已编成的霍夫曼码

%pro:输入的一组概率

%ecode:最终完成的码

l=length(code);

ecode=cell(l,2);

for i=1:l

    lang(i)=length(code{i});

end

[a,b]=sort(lang);

for i=1:l

    ecode{i,1}=code{b(i)};

    ecode{i,2}=pro(i);

end

function [final,a]=dealnum(imput,m)

%整理并在全局变量中输出已完成的霍夫曼码

%输入: imput:程序运算后的生成cell型矩阵

%       m:标识数

%输出: final:整理后的霍夫曼码

%       a:标识数

global lmlcode

global cellnum

if m==1

    lmlcode{cellnum}=imput;

    cellnum=cellnum+1;

    final='';

    a='';

else if m==2

        [final1,a1]=dealnum(imput{1,1},imput{1,2});

        [final2,a2]=dealnum(imput{2,1},imput{2,2});

        [final3,a3]=dealnum(final1,a1);

        [final4,a4]=dealnum(final2,a2);

        final=[final3 final4];

        a=[a3 a4];

    else

        final=imput;

        a=m;

    end

end

function [outnum,p]=findsumother(sequ,i,j,l,add_num)

%当前检索目标在sequ(i,j)处为非1时的处理程序,即跳转到下一级进行整理

%输入: sequ:概率转移矩阵

%       (i,j):当前检索目标在sequ矩阵中的位置

%       l:sequ矩阵的列数

%       add_num:当前进行的编码

%输出:(与disgress类同)

%       outnum:进行霍夫曼编码,用cell型表示

%       p:标识数

j=l-i+2-sequ(i,j);

i=i-1;

[add_num1]=addnum(add_num,i,j,l);

[outnum,p]=disgress(sequ,i,j,l,add_num1);

function [outnum1,outnum2,p,q]=findsumis1(sequ,i,j,l,add_num)

%当前检索目标在sequ(i,j)处为1时的处理程序,

%即对下一级的最小两概率进行求和移位编码整理

%输入: sequ:概率转移

%       (i,j):当前检索目标在sequ矩阵中的位置

%       l:sequ矩阵的列数

%       add_num:当前进行的编码

%输出:(与disgress类同)

%       outnum1&[outnum2:进行霍夫曼编码,用cell型表示

%       p&q:标识数

i=i-1;

j1=l-i;

j2=l-i+1;

[add_num1]=addnum(add_num,i,j1,l);

[outnum1,p]=disgress(sequ,i,j1,l,add_num1);

[add_num2]=addnum(add_num,i,j2,l);

[outnum2,q]=disgress(sequ,i,j2,l,add_num2);

function [output,m]=disgress(sequ,i,j,l,add_num)

%当前检索目标,累加数,输出下一级霍夫曼码及其个数,此函数被调用次数最多

%输入:sequ:概率转移矩阵

%      (i,j):当前检索目标在sequ矩阵中的位置

%      l:sequ矩阵的列数

%      add_num:当前进行的编码

%输出:output:进行霍夫曼编码,用cell型表示

%      m:标识数

%PS:此函数为编码第二步

if i~=1

    if sequ(i,j)==1

        [output1,output2,p,q]=findsumis1(sequ,i,j,l,add_num);

        output=cell(2);

        output{1,1}=output1;

        output{1,2}=p;

        output{2,1}=output2;

        output{2,2}=q;

        m=2;

    else if sequ(i,j)~=1

            [output1,p]=findsumother(sequ,i,j,l,add_num);

            output=output1;

            m=p;

        end

    end

else

    output=add_num;

    m=1;

end

五、实验程序实现方法演示

若在command window中输入的概率数组为p=[0.1 0.15 0.20 0.25 0.30]使用子函数[output,sequ,i,j]=probality(p)对此组概率进行预处理,处理结果如下图所示:

图5.1  概率数据处理过程简图

图5.2  对图1中数据的转移方式标示图

图2标明了对图1中各数据的位置转移过程。图1中每一列最后两个数据标为1,其他数据从下到上依次标为2、3、4...如第一列最后两个数据标为1,则其上依次为2、3、4。故在第二列中sequ(2,3)=1的含义是:output(2,3)=0.25为第一列中标为1的数据转移而来;sequ(2,2)=3的含义是:output(2,2)=0.25为第一列中标为3的数据转移而来;在第三列中sequ(2,3)=3的含义是:output(2,3)=0.3为第二列中标为3的数据转移而来,等等。

依据矩阵outputsequ可以得到霍夫曼编码的码树图如下:

图5.3  特定概率数组的编码码树

六、结果分析与总结

(1)实验结果分析

1、在command window中输入:p=[0.1 0.15 0.20 0.25 0.30],生成数组p

2、之后在command window中输入:[a]=lml_huffman(p),输出结果为:

a =

       '00'     [0.3000]

       '01'     [0.2500]

       '11'     [0.2000]

       '100'    [0.1500]

       '101'    [0.1000]

其中outnum为cell型,第一列为字符型,输出的是霍夫曼码,第二列为输入的概率数组,与第一列中的霍夫曼码相对应。

将以上输出结果在下表中统计。

表6.1  编码分析表

(2)实验小结

1、从实验结果可以看出,霍夫曼编码的效率很高,但是并未达到可以达到100%

2、从实验程序可以看出,每次对信源缩减时,赋予信源最后两个概率最小的符号,用0和1是可以任意的,所以可以得到不同的霍夫曼码,但不会影响码字的平均长度。

教师签名:

         年    月     日


第二篇:编码理论实验报告实验一霍夫曼编码中信息熵及编码效率的实验


实验名称 实验一    霍夫曼编码中信息熵及编码效率的实验

一、 实验目的

1.  掌握霍夫曼编码中信息熵的定义、性质和计算;

2.  掌握霍夫曼编码中平均码字长度的定义和计算;

3. 掌握霍夫曼编码中编码效率的定义和计算;

4.  正确使用C语言实现霍夫曼编码中信息熵、平均码长和编码效率的求取。

二、实验内容

1.  熟练列出霍夫曼编码中信息熵、平均码长和编码效率各自的计算公式;

2.  正确使用C语言实现计算霍夫曼编码中信息熵、平均码长和编码效率的程序,并在Visual C++环境中验证。

三、 实验原理

1.  霍夫曼编码的基本原理

按照概率大小顺序排列信源符号,并设法按逆顺序分配码字字长,使编码的码字为可辨识的。

2.  平均码长:L=∑p(si)*l(单位为:码符号/信源符号)

其中,p(si)为信源si在q个信源中出现的概率,li为信源si的二进制霍夫曼编码。

3.  信息熵:H(S)=- ∑p(si) *log2 p(si)  (单位为:比特/信源符号)

其中,p(si)为信源si在q个信源中出现的概率。

4.  编码效率:η= H(S)/ L

其中,H(S)为信息熵,L为平均码长。

四、 实验步骤:

1.  Huffman编码示例如下图:

2.  根据Huffman编码的例子,用C语言完成计算霍夫曼编码中信息熵的程序的编写,并在Visual C++环境中验证;

3.  根据Huffman编码的例子,用C语言完成计算霍夫曼编码中平均码长的程序的编写,并在Visual C++环境中验证;

4.  根据Huffman编码的例子,用C语言完成计算霍夫曼编码中编码效率的程序的编写,并在Visual C++环境中验证;

实验程序:

/*********** 霍夫曼编码信息熵、平均码长及编码效率的计算 ************

//按照实验步骤的要求完成程序,正确计算霍夫曼编码的信息熵、

//平均码长以及编码效率,并通过printf函数将三者的计算结果

//打印出来

#include<stdio.h>

#include<string.h>

#include<math.h>

#define  CH_Num   5        //信源符号个数

//主函数

void main()

{

    //编程1:定义double型数组gailv存放各信源符号出现的概率

    double gailv[CH_Num]={0.4,0.2,0.2,0.15,0.05};

    

    //编程2:定义int型数组code_len存放各信源符号的霍夫曼编码

    int code_len[CH_Num]={2,2,2,3,3};

   //编程3:定义double型变量aver_Len、Hs和code_ratio,分别

   //对应信息熵、平均码长及编码效率,并初始化为0

    double aver_Len=0,Hs=0,code_ratio=0;

    int i;

   //编程4:利用for循环计算平均码长aver_Len

   for(i=0;i<CH_Num;i++)

      aver_Len+=gailv[i]*code_len[i];

   //编程5:利用for循环计算信息熵Hs

    for(i=0;i<CH_Num;++i)

      Hs+=-(gailv[i]*(log(gailv[i])/log(2)));

  

   //编程6:计算编码效率code_ratio

   code_ratio=Hs/aver_Len;

   

    //编程7:利用三条printf语句分别打印平均码长、信息熵和编码效率

    printf("平均码长=%lf  比特/信源符号\n",aver_Len);

   printf("信源熵=%lf  码符号/信源符号\n",Hs);

   printf("编码效率=%lf\n",code_ratio);

}

运行结果如下图:

实验心得:通过本次试验加深了对霍夫曼编码的基本原理的理解以及计算公式的记忆。并使用C语言实现计算霍夫曼编码中信息熵、平均码长和编码效率的程

序,并在Visual C++环境中验证,且结果正确。

更多相关推荐:
哈夫曼编码实验报告

哈夫曼编码器实验报告学院:计算机学院班级:计科0801班姓名:***学号:***一.实验目的练习树和哈夫曼树的有关操作,和各个算法程序,理解哈夫曼树的编码和译码二.实验环境Microsoftvisualc++三…

C语言-哈夫曼编码实验报告

福建工程学院课程设计课程数据结构题目哈夫曼编码和译码专业信息管理信息系统班级座号15号姓名林左权20xx年6月27日1实验题目哈夫曼编码和译码一要解决的问题利用哈夫曼编码进行信息通信可以大大提高信道利用率缩短信...

哈夫曼编码译码系统课程设计实验报告(含源代码C++_C语言)[1]

东北电力大学计算机科学与技术专业综合设计报告目录摘要IIAbstractII第一章课题描述111问题描述112需求分析113程序设计目标第二章设计简介及设计方案论述221设计简介222设计方案论述223概要设计...

霍夫曼编码实验报告(C++)

计算机科学与工程系一实验名称霍夫曼编码二实验环境软件环境Windows20xxMicrosoftVisualC60硬件环境P424GHz256内存IBMPC及兼容机三实验目的掌握霍夫曼编码译码原理并能够通过程序...

哈夫曼编码实验报告

数据结构实验班级软件C092姓名孙琼芳学号098586一实验目的利用哈夫曼编码进行通信可以大大提高信道利用率缩短信息传输时间降低传输成本但是这要求在发送端通过一个编码系统对待传数据预先编码在接收端将传来的数据进...

哈夫曼编码实验报告

实验报告与总结一实验目的1掌握哈夫曼编码原理2熟练掌握哈夫曼树的生成方法3理解数据编码压缩和译码输出编码的实现二实验要求实现哈夫曼编码和译码的生成算法三实验内容先统计要压缩编码的文件中的字符字母出现的次数按字符...

哈夫曼编码实验报告

北京邮电大学信息与通信工程学院数据结构实验报告实验名称实验三哈夫曼编码学生姓名牛佳宁班级20xx211107班内序号27学号10210213日期20xx年12月10日1实验要求利用二叉树结构实现赫夫曼编解码器1...

哈夫曼编码实验报告

数据结构作业报告哈夫曼编码实验报告姓名班级学号摘要本程序能执行让一段字符以哈夫曼编码的形式被转存或将一段哈夫曼编码翻译成字符通过字符的频率统计哈夫曼树的建立递归求字符的哈夫曼编码完成这个程序让我熟悉哈夫曼编码的...

数据结构+哈夫曼编码+实验报告

实验报告一实验目的掌握哈夫曼树及其应用二实验内容利用哈夫曼算法构造最优二叉树然后对构造好的二叉树的叶子结点进行前缀编码三实验步骤1审清题意分析并理出解决问题的基本思路2根据基本思路设计好程序的算法3根据算法编写...

数据结构 哈夫曼编码 实验报告

数据结构实验报告实验名称:实验3树(哈夫曼编/解码器)学生姓名:班级:班内序号:学号:日期:20##年12月5日1.实验要求利用二叉树结构实现哈夫曼编/解码器。基本要求:1、初始化(Init):能够对输入的任意…

哈夫曼编码实验报告

中南大学数据结构课程姓名刘阳班级信息0703学号0903070312实验时间081114指导老师赵颖

2.基尔霍夫定律和叠加原理的验证(实验报告答案)含数据处理

实验二基尔霍夫定律和叠加原理的验证一实验目的1验证基尔霍夫定律的正确性加深对基尔霍夫定律的理解2验证线性电路中叠加原理的正确性及其适用范围加深对线性电路的叠加性和齐次性的认识和理解3进一步掌握仪器仪表的使用方法...

霍夫曼编码实验报告(37篇)