中南大学
信息论与编码实验报告
选 题: 费诺编码
学生姓名:
学 号:
专业班级: 通信工程
指导老师:
学 院: 信息科学与工程学院
时 间: 2015
目录
一、实验目的
二、实验原理
2.1 费诺编码思想
2.2 费诺编码流程图
三、实验内容
四、实验要求
五、代码调试结果
六、心得体会
七、程序源代码
一实验目的
1. 掌握费诺编码的原理和过程。
2. 熟悉 C/C++语言,练习使用C/C++实现香农码和Huffman 编码。
二、实验原理
2.1 费诺编码思想
设有离散无记忆信源
1.按信源符号的概率从大到小的顺序排队
不妨设
2.将依次排列的信源符号按概率值分为两大组,使两个组的概率之和近似相同,并对各组赋予一个二进制码元“0”和“1”。
3.将每一大组的信源符号再分为两组,使划分后的两个组的概率之和近似相同,并对各组赋予一个二进制符号“0”和“1”。
4.如此重复,直至每个组只剩下一个信源符号为止。
5.信源符号所对应的码字即为费诺码。
例:有一单符号离散无记忆信源
对该信源编二进制费诺码
2.2 费诺编码流程图
三、实验内容
使用C\C++实现费诺编码,并自己设计测试案例。
四、实验要求
1.提前预习实验,认真阅读实验原理以及相应的参考书。
2.认真高效的完成实验,实验中服从实验室管理人员以及实验指导老师的管理。
3.认真撰写实验报告,内容可以自己编排,可以考虑包括以下一些方面:原理概述、程序设计与算法描述、源程序及注释(程序太长可以只选取重要部分)、运行输出结果实例、调试和运行程序过程中产生的问题及采取的措施、对实验的讨论分析、总结。
五、代码调试结果
六、心得体会
通过本次试验,熟悉了c++的使用方法以及在信息论中的使用方法,加强了课程框架的理解。在这次实验中,再次对信息论与编码有了更深层的理解,以前只是通过书上的理论推导,对相关的计算不是特别理解,通过这次的上机实际操作,以及函数图形的绘制,让我对熵函数有了更多的感性认识。对费诺编码的理论了解得更透彻。
总的来说,不仅是实验的结果,更重要的是过程和思考,是我学到了很多的知识,真的是受益匪浅。
七、实验代码
#include<iostream.h>
#include<math.h>
#include<windows.h>
#define N 15
int pa[N][N];
void fano(float p[],int a[N][N],int n,int m,int k) //fano编码算法
{
float g=0.0,h=0.0,d,b,c;
int i,j;
if(n<m)
{
for(i=n;i<=m;i++)
{
g=p[i]+g;
}
g=g/2;
for(i=n;i<=m;i++)
{
h=h+p[i];
if(h>g)
{
d=h-p[i];
b=h-g;
c=g-d;
if(c>b)
{
for(j=n;j<=i;j++) a[j][k]=0;
fano(p,a,n,i,k+1);
for(j=i+1;j<=m;j++) a[j][k]=1;
fano(p,a,i+1,m,k+1);
}
else
{
for(j=n;j<=i-1;j++) a[j][k]=0;
fano(p,a,n,i-1,k+1);
for(j=i;j<=m;j++) a[j][k]=1;
fano(p,a,i,m,k+1);
}
break;
}
}
}
}
void select() //初始化选择,实现编码
{
void display(); //函数声明
void choose(); //函数声明
int i,j,k[N],n,flase=0;
float p[N],H=0.0,K=0.0,sum=0.0;
cout<<"请输入信源符号个数:"<<endl;
cin>>n;
cout<<"请输入各信源符号概率:"<<endl;
for(i=1;i<=n;i++)
{
cin>>p[i];
}
for(i=1;i<=n;i++)
{
sum=sum+p[i];
}
for(i=1;i<=n;i++)
{
if(p[i]<0.0||p[i]>1.0||sum!=1.0)
{
cout<<"输入概率有错,请重新输入!"<<endl<<endl;
display();
choose();
}
}
if(flase==0)
{
for(i=0;i<=n;i++)
for(j=0;j<=n;j++)
{
pa[i][j]=10;
}
fano(p,pa,1,n,1);
cout<<"信源费诺编码如下:\n"<<endl;
cout<<"概率"<<"\t码字为\t"<<"码长为\t"<<endl;
for(i=1;i<=n;i++)
{
k[i]=0;
cout<<"x"<<i<<"="<<p[i]<<"\t";
for(j=1;j<=n;j++)
{
if(pa[i][j]!=10)
{
cout<<pa[i][j];k[i]++;}
}
cout<<"\t"<<k[i]<<endl;
}
for(i=1;i<=n;i++)
{
H=-(p[i]*log(p[i])/log(2))+H;
}
cout<<endl<<"信源熵 H(X)="<<H<<" (比特/符号)"<<endl<<endl;
for(i=1;i<=n;i++)
{
K=p[i]*k[i]+K;
}
cout<<"平均码长 K="<<K<<" (比特/符号)"<<endl<<endl;
cout<<"编码效率为 "<<(H/K)*100<<"%"<<endl;
}
display();
choose();
}
void display()
{
cout<<endl<<"选择:"<<endl;
cout<<"1.费诺编码:"<<endl;
cout<<"2.退出:"<<endl;
}
void choose()
{
int a;
cin>>a;
if(a==1)
select();
else if(a==2)
exit(0);
else
{
cout<<"请重新选择:"<<endl;
choose();
}
}
void main()
{
cout<<"---------------------费诺编码实验------------------"<<endl<<endl;
display();
choose();
system("pause");
}
第二篇:信息论编码实验报告
实验2 编程实现香农信源编码
一、实验内容
利用 MATLAB 实现香农编码信源编码方法。
二、实验环境
1. 计算机
2. Windows XP 或以上
3. Matlab 6.0 或以上
三、实验目的
1. 掌握 Matlab 绘图函数
2. 掌握、理解常见经典信源编码算法
四、实验要求
1. 提前预习实验,认真阅读实验原理以及相应的参考书。
2. 认真高效的完成实验,实验中服从实验室管理人员以及实验指导老师的管理。
五、实验原理
设离散无记忆信源
二进制香农码的编码步骤如下:
1、将信源符号按概率从大到小的顺序排列,为方便起见,令 p(x1)≥ p(x2)≥…
≥ p(xn)
2、令p(x0)=0,用pa(xj),j=i+1 表示第i 个码字的累加概率,则:
3、确定满足下列不等式的整数ki ,并令ki 为第i 个码字的长度
-log2 p(xn)≤ki<- log2 p(xn)+1
4、将pa(xj) 用二进制表示,并取小数点后ki 位作为符号xi 的编码。
六、实验内容
有一单符号离散无记忆信源
编程实现其二进制的香农编码。
function c=shannon(p)
p=[0.25 0.25 0.20 0.15 0.10 0.05]
[p,index]=sort(p);
p=fliplr(p);
n=length(p);
pa=0;
for i=2:n
pa(i)=pa(i-1)+p(i-1);
end
k=ceil(-log2(p));
c=cell(1,n)
for i=1:n
c{i}= '';
tmp=pa(i);
for j=1:k(i)
tmp=tmp * 2;
if tmp>=1
tmp=tmp - 1;
c{i}(j)= '1';
else
c{i}(j)= '0';
end
end
end
c=fliplr(c);
c(index)=c;
实验结果: