实验1道容量的迭代算法.docx
- 文档编号:26050405
- 上传时间:2023-06-17
- 格式:DOCX
- 页数:21
- 大小:64.41KB
实验1道容量的迭代算法.docx
《实验1道容量的迭代算法.docx》由会员分享,可在线阅读,更多相关《实验1道容量的迭代算法.docx(21页珍藏版)》请在冰豆网上搜索。
实验1道容量的迭代算法
《信息论基础实验》
指导老师:
贺正芸
班级:
信息工程081
姓名:
卢慈荣
学号:
湖南工业大学
电气与信息工程学院
实验一信道容量的迭代算法程序设计
一、实验目的
(1)进一步熟悉信道容量的迭代算法;
(2)学习如何将复杂的公式转化为程序;
(3)掌握C语言数值计算程序的设计和调试技术。
二、实验要求
(1)已知:
信源符号个数r、信宿符号个数s、信道转移概率矩阵P。
(2)输入:
任意的一个信道转移概率矩阵。
信源符号个数、信宿符号个数和每个具体的转移概率在运行时从键盘输入。
(3)输出:
最佳信源分布P*,信道容量C。
三、信道容量迭代算法
1:
procedureCHANNELCAPACITY(r,s,(
))
2:
initialize:
信源分布
=1/r,相对误差门限
,C=—
3:
repeat
4:
5:
6:
C←
7:
until
8:
outputP*=
C
9:
endprocedure
-------------------------------------------------------------------------------------------------------
四、实验代码
/*
问题:
1 初始最大容量的设定
2 exp的精确求解
*/
#include
#include
#include
#include
#include
#defineR1000
#defineS1000
#definedelta1e-2
#defineinf1e6
usingnamespacestd;
doubleP_i[R],P_ji[S][R],Thi_ij[R][S];
doublePre_C,Now_C;
intr,s,Num;
double__log2(doublea)
{
returnlog(a)/log
(2);
}
double__exp(doublea)
{
returnpow(2.7045,a);
}
inteps(doublea)
{
if(a>delta||a<-delta)return1;return0;
}
voidscan()
{
inti,j,k;
intflag=0;
doublet;
freopen("信道信息.txt","r",stdin);
printf("本次信道信息如下:
(若要更改信道信息,请终止程序运行后,改变文件信道信息.txt中的信息)\n");
printf("信源处信息的个数:
");
scanf("%d",&r);
printf("%d\n\n",r);
printf("信道接收处信息的种类:
");
scanf("%d",&s);
printf("%d\n\n",s);
printf("信道的分配(每一行表示信源处的一个信息对接收端一处信息的概率分布):
\n");
for(i=0;i { t=0.0; for(j=0;j {scanf("%lf",&P_ji[j][i]); if(P_ji[j][i]<0)flag=1; t+=P_ji[j][i]; } if(eps(t-1.0))flag=1; } for(i=0;i { for(j=0;j printf("%lf",P_ji[j][i]); printf("\n"); } if(flag) printf("信道数据有误! \n"); } voidprint() { inti,j,k; printf("\n\n\t\t运行结果\n\n最大的信息容量是: %lf.\n",Now_C); printf("\n迭代次数是%d.\n",Num); printf("\n信源信息概率分布为: \n"); for(i=0;i printf("%.6lf",P_i[i]); printf("\n\n"); printf("后验概率分布是(每一行表示接收端一种信息的来源概率分布): \n"); for(j=0;j { for(i=0;i printf("%.6lf",Thi_ij[i][j]); printf("\n"); } } voidrun() { inti,j,k; doubleP_j,sum; for(i=0;i P_i[i]=1.0/r; Now_C=0; Num=0; while (1) { Num++; for(j=0;j { P_j=0.0; for(i=0;i P_j+=P_i[i]*P_ji[j][i]; if(fabs(P_j)>=delta) for(i=0;i Thi_ij[i][j]=P_i[i]*P_ji[j][i]/P_j; else for(i=0;i Thi_ij[i][j]=0.0; } sum=0.0;//求P_i for(i=0;i { P_i[i]=0.0; for(j=0;j if(fabs(Thi_ij[i][j])>delta) P_i[i]+=P_ji[j][i]*__log2(Thi_ij[i][j]); P_i[i]=__exp(P_i[i]); sum+=P_i[i]; } if(fabs(sum)>=delta) for(i=0;i P_i[i]/=sum; else for(i=0;i P_i[i]=0.0; Pre_C=Now_C;//前后两次迭代的容量进行比较,达到一定的精确度时退出循环,进行输出 Now_C=-__log2(sum); if(fabs((Pre_C-Now_C)/Now_C)<=delta) { print(); break; } } } intmain() { scan(); run(); while (1); system("pause"); return0; } 五、实验结果 实验二唯一可译码判决准则 一、实验目的 (1)进一步熟悉唯一可译码判决准则; (2)掌握C语言字符串处理程序的设计和调试技术。 二、实验要求 (1)已知: 信源符号个数q、码字集合C。 (2)输入: 任意的一个码。 码字个数和每个具体的码字在运行时从键盘输入。 (3)输出: 判决(是唯一可译码/不是唯一可译码)。 3.程序设计代码: #include #include #include structstrings { char*string; structstrings*next; }; structstringsFstr,*Fh,*FP; //输出当前集合 voidoutputstr(strings*str) { do { cout< str=str->next; }while(str); cout< } inlineintMIN(inta,intb) {returna>b? b: a;} inlineintMAX(inta,intb) {returna>b? a: b;} #definelength_a(strlen(CP)) #definelength_b(strlen(tempPtr)) //判断一个码是否在一个码集合中,在则返回0,不在返回1 intcomparing(strings*st_string,char*code) { while(st_string->next) { st_string=st_string->next; if(! strcmp(st_string->string,code)) return0; } return1; } //判断两个码字是否一个是另一个的前缀,如果是则生成后缀码 voidhouzhui(char*CP,char*tempPtr) { if(! strcmp(CP,tempPtr)) { cout<<"集合C和集合F中有相同码字: "< < <<"不是唯一可译码码组! "< exit (1); } if(! strncmp(CP,tempPtr,MIN(length_a,length_b))) { structstrings*cp_temp; cp_temp=new(structstrings); cp_temp->next=NULL; cp_temp->string=newchar[abs(length_a-length_b)+1]; char*longstr; longstr=(length_a>length_b? CP: tempPtr);//将长度长的码赋给longstr //取出后缀 for(intk=MIN(length_a,length_b);k cp_temp->string[k-MIN(length_a,length_b)]=longstr[k]; cp_temp->string[abs(length_a-length_b)]=NULL; //判断新生成的后缀码是否已在集合F里,不在则加入F集合 if(comparing(Fh,cp_temp->string)) { FP->next=cp_temp; FP=FP->next; } } } voidmain() { //功能提示和程序初始化准备 cout<<"\t\t唯一可译码的判断! \n"< structstringsCstr,*Ch,*CP,*tempPtr; Ch=&Cstr; CP=Ch; Fh=&Fstr; FP=Fh; charc[]="C: "; Ch->string=newchar[strlen(c)]; strcpy(Ch->string,c); Ch->next=NULL; charf[]="F: "; Fh->string=newchar[strlen(f)]; strcpy(Fh->string,f); Fh->next=NULL; //输入待检测码的个数 intCnum; cout<<"输入待检测码的个数: "; cin>>Cnum; cout<<"输入待检测码"< for(inti=0;i { cout< "; chartempstr[10]; cin>>tempstr; CP->next=new(structstrings); CP=CP->next; CP->string=newchar[strlen(tempstr)]; strcpy(CP->string,tempstr); CP->next=NULL; } outputstr(Ch); CP=Ch; while(CP->next->next) { CP=CP->next; tempPtr=CP; do { tempPtr=tempPtr->next; houzhui(CP->string,tempPtr->string); }while(tempPtr->next); } outputstr(Fh); structstrings*Fbegin,*Fend; Fend=Fh; while (1) { if(Fend==FP) { cout<<"是唯一可译码码组! "< exit (1); } Fbegin=Fend; Fend=FP; CP=Ch; while(CP->next) { CP=CP->next; tempPtr=Fbegin; for(;;) { tempPtr=tempPtr->next; houzhui(CP->string,tempPtr->string); if(tempPtr==Fend) break; } } outputstr(Fh);//输出F集合中全部元素 } } 4.输入、输出结果: 例1: 输入: 唯一可译码的判断! 输入待检测码的个数: 5 输入待检测码 1: xx 2: xz 3: y 4: zz 5: xyz C: xx xz y zz xyz F: 是唯一可译码码组! Pressanykeytocontinue 实验三Huffman编码方案程序设计 一、实验目的 (1)进一步熟悉Huffman编码过程; (2)掌握C语言递归程序的设计和调试技术。 二、实验要求 (1)输入: 信源符号个数r、信源的概率分布P; (2)输出: 每个信源符号对应的Huffman编码的码字。 三、算法 1、从键盘输入组成信源C的字符个数N; 2、从键盘输入信源C和组成信源的字符所对应的概率数组P; 3、用 函数来对信源进行二进制编码;先对P按从大到小进行排序,与此同时要把C中相应的字符的位置做相应的调换;用 数组来记录编码: 在进行记录编码时是从数组 的最后一个开始存储的,而且,每进行一次编码所记录下来的两个编码 是按从数组的最后一个元素开始服从count[m-k-j]、count[m-k-j-1],其中k表示编码所进行的次数,j表示每次编码都只有 ;最后用函数 来输出编码。 四、代码 #include #include #include intm,s1,s2; typedefstruct{ unsignedintweight; unsignedintparent,lchild,rchild; }HTNode,*HuffmanTree;//动态分配数组存储哈夫曼树 typedefchar*HuffmanCode;//动态分配数组存储哈夫曼编码表 voidSelect(HuffmanTreeHT,intn){ inti,j; for(i=1;i<=n;i++) if(! HT[i].parent){s1=i;break;} for(j=i+1;j<=n;j++) if(! HT[j].parent){s2=j;break;} for(i=1;i<=n;i++) if((HT[s1].weight>HT[i].weight)&&(! HT[i].parent)&&(s2! =i))s1=i; for(j=1;j<=n;j++) if((HT[s2].weight>HT[j].weight)&&(! HT[j].parent)&&(s1! =j))s2=j; } voidHuffmanCoding(HuffmanTree&HT,HuffmanCodeHC[],int*w,intn){ //算法6.13 //w存放n个字符的权值(均>0),构造哈夫曼树HT, //并求出n个字符的哈夫曼编码HC inti,j; char*cd; intp; intcdlen; if(n<=1)return; m=2*n-1; HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode));//0号单元未用 for(i=1;i<=n;i++){//初始化 HT[i].weight=w[i-1]; HT[i].parent=0; HT[i].lchild=0; HT[i].rchild=0; } for(i=n+1;i<=m;i++){//初始化 HT[i].weight=0; HT[i].parent=0; HT[i].lchild=0; HT[i].rchild=0; } puts("\n哈夫曼树的构造过程如下所示: "); printf("HT初态: \n结点weightparentlchildrchild"); for(i=1;i<=m;i++) printf("\n%4d%8d%8d%8d%8d",i,HT[i].weight, HT[i].parent,HT[i].lchild,HT[i].rchild); printf("按任意键,继续..."); getchar(); for(i=n+1;i<=m;i++){//建哈夫曼树 //在HT[1..i-1]中选择parent为0且weight最小的两个结点, //其序号分别为s1和s2。 Select(HT,i-1); HT[s1].parent=i;HT[s2].parent=i; HT[i].lchild=s1;HT[i].rchild=s2; HT[i].weight=HT[s1].weight+HT[s2].weight; printf("\nselect: s1=%ds2=%d\n",s1,s2); printf("结点weightparentlchildrchild"); for(j=1;j<=i;j++) printf("\n%4d%8d%8d%8d%8d",j,HT[j].weight, HT[j].parent,HT[j].lchild,HT[j].rchild); printf("按任意键,继续..."); getchar(); } //------无栈非递归遍历哈夫曼树,求哈夫曼编码 cd=(char*)malloc(n*sizeof(char));//分配求编码的工作空间 p=m;cdlen=0; for(i=1;i<=m;++i)//遍历哈夫曼树时用作结点状态标志 HT[i].weight=0; while(p){ if(HT[p].weight==0){//向左 HT[p].weight=1; if(HT[p].lchild! =0){p=HT[p].lchild;cd[cdlen++]='0';} elseif(HT[p].rchild==0){//登记叶子结点的字符的编码 HC[p]=(char*)malloc((cdlen+1)*sizeof(char)); cd[cdlen]='\0';strcpy(HC[p],cd);//复制编码(串) } }elseif(HT[p].weight==1){//向右 HT[p].weight=2; if(HT[p].rchild! =0){p=HT[p].rchild;cd[cdlen++]='1';} }else{//HT[p].weight==2,退回退到父结点,编码长度减1 HT[p].weight=0;p=HT[p].parent;--cdlen; } } }//HuffmanCoding voidmain(){ HuffmanTreeHT;HuffmanCode*HC;int*w,n,i; puts("输入结点数: "); scanf("%d",&n); HC=(HuffmanCode*)malloc(n*sizeof(HuffmanCode)); w=(int*)malloc(n*sizeof(int)); printf("输入%d个结点的权值\n",n); for(i=0;i scanf("%d",&w[i]); HuffmanCoding(HT,HC,w,n); puts("\n各结点的哈夫曼编码: "); for(i=1;i<=n;i++) printf("%2d(%4d): %s\n",i,w[i-1],HC[i]); getchar(); } 四、运行结果 输入节点数5 五个节点权值: 512321375 五、实验总结 本实验使用c语言编写,用Huffman函数来对信源进行二进制编码,由于对Huffman比较熟悉,编写起来也比较简单,程序先对P按从大到小进行排序,与此同时要把C中相应的字符的位置做相应的调换,本实验很好的复习了Huffman的内容,对于信息论与编码的巩固也有很大的好处,同时也是对C使用技巧的提高。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实验 容量 算法