Matlab-Huffman编码

信息论实验课的第二个作业。

捣鼓了半天(别人的代码)总算捣鼓明白了……

虽然只懂了二元的=。=

clc;
clear;
%输入格式:[p1 p2 p3 … pn]
%A = [0.1 0.18 0.4 0.05 0.06 0.1 0.07 0.04];    

A = input('输入信源概率分布:\n')
n = length(A);
%----先判断输入格式是否正确
for i = 1:n
    if A(i)<0
    fprintf('概率小于0,请重新输入。\n');
    A = input('输入信源概率分布:\n')
    end
end

A = sort(A,'descend');  %降序排列        
T = A;%设置一个当前编码序列
[m,n] = size(A);%行列数
B=zeros(n,n-1);%生成一个空的编码表
%-----编码表的第一列
for i=1:n
    B(i,1)=T(i);
end
sum=B(i,1)+B(i-1,1);%最后两个概率相加
T(n-1)=sum;
T(n)=0;%把刚所求最后两个数之和放进当前编码序列,最后一个设置为0
T = sort(T,'descend');%然后重新进行排序
t = n-1;%当前序列数目

%-----编码表的其他列
for j=2:n-1 %从第二列开始
    for i=1:t
        B(i,j)=T(i);
    end
        K=find(T==sum);  %找到当前序列中sum的位置,记在K中
        B(n,j)=K(end);%从第二列开始,编码表中的最后一位元素是sum在当前序列中的位置
        sum=(B(t-1,j)+B(t,j));%继续把最后两个元素相加记为sum
        T(t-1)=sum;
        T(t)=0;%把刚所求最后两个数之和放进当前编码序列,最后一个设置为0
        T = sort(T,'descend'); %然后重新进行排序
        t=t-1;%当前序列数目
end
%编码表
disp('编码表为:')
B
%-----开始编码
%先设置最后一列的两个元素编码为0和1
%这里写下划线是因为matlab会显示不出来0,所以只能加上下划线让它显示出来
%因为有下划线,所以后面计算码长的时候会除2
END1=sym('[_0,_1]'); 
END=END1;
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
         %把相加后的那个数设置为-1方便找到
        B(B(n,j+1),j+1)=-1;          
        temp=B(:,j+1);                
        x=find(temp==B(i,j)); 
        %给没有变过的值编码
        END(i)=END1(x(d));            
    end
    y=B(n,j+1);
    %给变过的值编码,上面的补0,下面的补1
    END(t-1)=[char(END1(y)),'_0'];   
    END(t)=[char(END1(y)),'_1'];
    t=t+1;
    END1=END;
end
%编码结果
disp('编码结果为:')       
END
%-----计算编码效率p
for i=1:n
    [a,b]=size(char(END(i)));
    M(i)=b/2;    
end
%计算平均码长
L1 = 0;
for i=1:n
    L1 = L1 + M(i).*A(i);
end
%计算信息熵
H1=log2(A);
H=-A*(H1');
p=H/L1;
disp('编码效率为:')
p

运行结果:

输入信源概率分布:
[1/6 1/4 5/12 1/6]

A =

    0.1667    0.2500    0.4167    0.1667

编码表为:

B =

    0.4167    0.4167    0.5833
    0.2500    0.3333    0.4167
    0.1667    0.2500         0
    0.1667    2.0000    1.0000

编码结果为:
 
END =
 
[ _1, _0_1, _0_0_0, _0_0_1]
 
编码效率为:

p =

0.9850
输入信源概率分布:
[0.1 0.18 0.4 0.05 0.06 0.1 0.07 0.04]

A =

    0.1000    0.1800    0.4000    0.0500    0.0600    0.1000    0.0700    0.0400

编码表为:

B =

    0.4000    0.4000    0.4000    0.4000    0.4000    0.4000    0.6000
    0.1800    0.1800    0.1800    0.1900    0.2300    0.3700    0.4000
    0.1000    0.1000    0.1300    0.1800    0.1900    0.2300         0
    0.1000    0.1000    0.1000    0.1300    0.1800         0         0
    0.0700    0.0900    0.1000    0.1000         0         0         0
    0.0600    0.0700    0.0900         0         0         0         0
    0.0500    0.0600         0         0         0         0         0
    0.0400    5.0000    3.0000    2.0000    2.0000    2.0000    1.0000

编码结果为:
 
END =
 
[ _1, _0_0_1, _0_1_1, _0_0_0_0, _0_1_0_0, _0_1_0_1, _0_0_0_1_0, _0_0_0_1_1]
 
编码效率为:

p =

    0.9779

 

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值