这里对霍夫曼原理不做多加描述,主要讲解代码。
1.代码第一步主要是生成一个编码表B,它的第一列记录原始数据降序排列后的数,将两个最小的概率相加后,再进行排序记录到第二列,依次记录。以0.4 0.2 0.2 0.1 0.1为例
其中B的最后一行记录特征元素的行位置,特征元素是指两个最小概率之和相加的值。如,第一列0.1+0.1=0.2,因为在程序中设置了“若概率之和与原信源中的某概率相等,将概率之和向上排”,所以特征元素在第二行,记为2. 代码如下
clc;clear all;close all;
A=[0.4 0.2 0.2 0.1 0.1];
A=sort(A,'descend');%按降序排列
T=A;
[m,n]=size(A);%一行七列
B=zeros(n,n-1);%空的编码表(矩阵)
B(:,1)=T;%生成编码表的第一列
r=B(n,1)+B(n-1,1);%最后两个元素相加的值赋给r
T(n-1)=r;%令第n-1个数为r的值
T(n)=0;
T=sort(T,'descend');%将加完后的概率再次进行排序
t=n-1;
for j=2:n-1%生成编码表的其他各列,从第2列开始
B(1:t,j)=T(1:t);%B每一列记录相加完排序后的数列
K=find(T==r);%%T是向量,r是要查找的元素值,返回位置K
%B(n,j)=K(end);%从第二列开始,每列的最后一个元素记录特征元素在该列的位置 概率之和往下排
B(n,j)=K(1);%从第二列开始,每列的最后一个元素记录特征元素在该列的位置,概率之和往上排;
%如果合并后的概率与其他概率相等, 将合并概率当大概率排列
r=(B(t-1,j)+B(t,j));%最后两个元素相加
T(t-1)=r;
T(t)=0;
T=sort(T,'descend');
t=t-1;
end
B;%输出编码表
2.代码第二部分是进行编码
先对最后一列进行编码,大为1,小为0.
再从倒数第二列开始编码,这时候分为两部分编码,即其他概率和最小两个概率分别编码。
先对其他概率编码:
如,倒数第二列,对第一个0.4,先查找到它在后一列的位置,根据位置取出它的编码,把这个编码加到0.4 的前面。因为这个0.4不是两个最小概率,不用相加,那么进行下一次排序后的编码仍然是相同的。
注意,这里有一行代码 B(B(n,j+1),j+1)=-1; 令后面一列特征元素为-1,是为避免在查找位置查错了。这里以倒数第三列为例,对于0.4和0.2,查找0.4在后一列的位置时有两个0.4,其中有一个为特征元素,所以令特征元素为-1,可以准确查到0.4的位置。
对最小两个概率编码,它是先查找特征元素的位置,取出特征元素的编码,加到他们俩前面,再大的加1,小的加0.如,从倒数第二列开始,特征元素为0.4+0.2=0.6,0.6在后一列的行数为1,取出它的编码为1,0.4大为11,0.2为10.代码如下
ENDc1={'1','0'};%给最后一列的元素编码
ENDc=ENDc1;
t=3;
d=1;
for j=n-2:-1:1%从倒数第二列开始依次对各列元素编码
for i=1:t-2
if i>1&&B(i,j)==B(i-1,j)
d=d+1;
else
d=1;
end
B(B(n,j+1),j+1)=-1;
temp=B(:,j+1);%令temp为B的第j+1列
x=find(temp==B(i,j));%X记录这一列前t-2个元素在后一列的位置
ENDc(i)=ENDc1(x(d));
end
%给每一列两个最小的概率编码,t-1,t
y=B(n,j+1);%最小两个元素相加的概率在后一列的位置
ENDc{t-1}=[ENDc1{y},'1'];%第t-1个元素在后一列的编码加到前面,并在后面加一
ENDc{t}=[ENDc1{y},'0'];
t=t+1;
ENDc1=ENDc;
end
A%排序后的原概率序列
ENDc%编码结果