費諾編碼

費諾編碼

費諾編碼,它編碼后的費諾碼要比香農碼的平均碼長小,消息傳輸速率達,編碼效率高,但它屬於概率匹配編碼它不是最佳的編碼方法。

費諾編碼基本原理


首先,將信源符號以概率遞減的次序排列進來,將排列好的信源符號劃分為兩大組,使第組的概率和近於相同,並各賦於一個二元碼符號”0”和”1”.然後,將每一大組的信源符號再分成兩組,使同一組的兩個小組的概率和近於相同,並又分別賦予一個二元碼符號。依次下去,直至每一個小組只剩下一個信源符號為止。這樣,信源符號所對應的碼符號序列則為編得的碼字。解碼原理,按照編碼的二叉樹從樹根開始,按解碼序列進行逐個的向其葉子結點走,直到找到相應的信源符號為止。之後再把指示標記回調到樹根,按照同樣的方式進行下一序列的解碼到序列結束。如果整個解碼序列能夠完整的譯出則返回成功,否則則返回解碼失敗。

費諾編碼的方法


1.將信源消息符號按其出現的概率大小依次排列。
2.將依次排列的信源符號按概率值分為兩大組,使兩個組的概率之和近似相同,並對各組賦予一個二進位碼元“0”和“1”。
3.將每一大組的信源符號再分為兩組,使劃分后的兩個組的概率之和近似相同,並對各組賦予一個二進位符號“0”和“1”。
4.如此重複,直至每個組只剩下一個信源符號為止。
5.信源符號所對應的碼字即為費諾碼。

程序實現


Matlab實現

編碼如下:
clc;
A=[0.4,0.3,0.1,0.09,0.07,0.04];
A=fliplr(sort(A));%降序排列
[m,n]=size(A);
for i=1:n
B(i,1)=A(i);%生成B的第1列
end
%生成B第2列的元素
a=sum(B(:,1))/2;
for k=1:n-1
if abs(sum(B(1:k,1))-a)<=abs(sum(B(1:k+1,1))-a)
break;
end
end
for i=1:n%生成B第2列的元素
if i<=k
B(i,2)=0;
else
B(i,2)=1;
end
end
%生成第一次編碼的結果
END=B(:,2)';
END=sym(END);
%生成第3列及以後幾列的各元素
j=3;
while (j~=0)
p=1;
while(p<=n)
x=B(p,j-1);
for q=p:n
if x==-1
break;
else
if B(q,j-1)==x
y=1;
continue;
else
y=0;
break;
end
end
end
if y==1
q=q+1;
end
if q==p|q-p==1
B(p,j)=-1;
else
if q-p==2
B(p,j)=0;
END(p)=[char(END(p)),'0'];
B(q-1,j)=1;
END(q-1)=[char(END(q-1)),'1'];
else
a=sum(B(p:q-1,1))/2;
for k=p:q-2
if abs(sum(B(p:k,1))-a)<=abs(sum(B(p:k+1,1))-a);
break;
end
end
for i=p:q-1
if i<=k
B(i,j)=0;
END(i)=[char(END(i)),'0'];
else
B(i,j)=1;
END(i)=[char(END(i)),'1'];
end
end
end
end
p=q;
end
C=B(:,j);
D=find(C==-1);
[e,f]=size(D);
if e==n
j=0;
else
j=j+1;
end
end
B
A
END
for i=1:n
[u,v]=size(char(END(i)));
L(i)=v;
end
avlen=sum(L.*A)

C++實現

#include
#include
#include
using namespace std;
#define MaxStrLength 50
#define MaxNode 24
#define MaxBit 5
typedef struct{
char Character;
float data;
int bit[MaxBit];
int length;
}CodeType;
CodeType FanoNode[MaxNode];
int Group(CodeType FanoNode[],int low,int high){
float MinSum=FanoNode[low].data,MaxSum=FanoNode[high].data;
FanoNode[low].bit[FanoNode[low].length++]=1;
FanoNode[high].bit[FanoNode[high].length++]=0;
while(low+1
if(MinSum>MaxSum){
MaxSum+=FanoNode[--high].data;
FanoNode[high].bit[FanoNode[high].length++]=0;
}
else{
MinSum+=FanoNode[++low].data;
FanoNode[low].bit[FanoNode[low].length++]=1;
}
}
return low;
}
void Disp(CodeType FanoNode[],int m,char str[],int SLength){
float K=0,R=0,H=0;
printf("MessageSymbol Character
Probability
CodeLength
Code\n");
for(int i=0;i
printf("FanoNode[%d]
%c
%.2f",i,FanoNode[i].Character,FanoNode[i].data);
%d
",FanoNode[i].length);
for(int j=0;j
printf("%d",FanoNode[i].bit[j]); printf("\n");
K+=FanoNode[i].data*FanoNode[i].length;
H+=-FanoNode[i].data*log(FanoNode[i].data);
}
printf("The code of the string is\n");
for(i=0;i
for(int k=0;k
if(FanoNode[k].Character==str[i]){
for(int j=0;j
printf("%d",FanoNode[k].bit[j]);
break;
}
R=H/K;
printf("\nThe average length of code is %.3f\n",K);
printf("The rate of transport is %.3f\n",R);
}
int IsnotIn(char a,char t[],int n,int count[]){
for(int k=0;k
if(a==t[k]){
count[k]++;
return 0;
}
return 1;
}
void ExChangeFloat(float p[],int i,int j){
float temp1;
temp1=p[i];
p[i]=p[j];
p[j]=temp1;
}
void ExChangeChar(char t[],int i,int j){
char temp2;
temp2=t[i];
t[i]=t[j];
t[j]=temp2;
}
void main(){
float p[MaxStrLength];
char str[MaxStrLength],t[MaxStrLength];
int count[MaxStrLength]={0},m=1;
printf("----------------------------FanoEncoding-----------------------\n");
printf("Please enter a string:");
scanf("%s",str);
for(int SLength=0;str[SLength]!='\0';SLength++)
printf("The total length of the string is %d\n",SLength);
t=str;
count++;
for(int i=1;i
if(IsnotIn(str[i],t,m,count)){
t[m]=str[i];
count[m++]++;
}
}
printf("The length of not repeating string is %d\n",m);
for(int j=0;j
p[j]=float(count[j])/float(SLength);
printf("The number of character %c appear is %d,Probability is %f\n",t[j],count[j],p[j]);
}
for(i=1;i
for(j=0;j
if(p[j]>p[j+1]){
ExChangeFloat(p,j,j+1);
ExChangeChar(t,j,j+1);
}
for(i=0;i
FanoNode[i].data=p[i];
FanoNode[i].length=0;
FanoNode[i].Character=t[i];
}
FanoEncoding(FanoNode,0,m-1);
Disp(FanoNode,m,str,SLength);
}