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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章