matlab練習程序(Kruskal最小生成樹)


老物了,網上的例子多的數不過來。不過我還是有必要練習一下的。

之所以看這個算法是因為最近在看顏色聚合向量時,有的論文用到了最小生成樹,因此我就拿來熟悉一下。

Kruskal算法類似於連通分支算法,感覺和過去實現過的連通區域標記算法非常像。

步驟:

1.對於一個圖,將圖的每條邊提取出來從小到大進行排序。

2.將已排序的邊依次加入到新圖中,如果新圖中出現了環,那么就舍棄這條邊。

3.不斷重復第二步。

下面兩個圖就是kruskal算法前后的樣子。

代碼如下:

main.m

clear all;
close all;
clc;
%算法導論P349的列子
G=[0 4 0 0 0 0 0 8 0;
   4 0 8 0 0 0 0 11 0;
   0 8 0 7 0 4 0 0 2;
   0 0 7 0 9 14 0 0 0;
   0 0 0 9 0 10 0 0 0;
   0 0 4 14 10 0 2 0 0;
   0 0 0 0 0 2 0 1 6;
   8 11 0 0 0 0 1 0 7;
   0 0 2 0 0 0 6 7 0];

[m n]=size(G);
E=[];
k=0;    %邊的數量
for i=1:m
    for j=i:n
        if G(i,j)~=0
            E=[E;G(i,j) i j];   %提取邊,三元組存儲
            k=k+1;
        end
    end
end

for i=k:-1:1                %按邊的權重排序,小的排前面
    for j=1:i-1
        if E(j,1)>E(j+1,1)
            tmp=E(j,:);
            E(j,:)=E(j+1,:);
            E(j+1,:)=tmp;
        end
    end
end

A=zeros(m,n);
for i=1:k  
    A(E(i,2),E(i,3))=E(i,1);
    A(E(i,3),E(i,2))=E(i,1);
    if huan(A)              %加入邊后判斷圖中是否含有環
        A(E(i,2),E(i,3))=0;
        A(E(i,3),E(i,2))=0;
    end
end

huan.m

function re=huan(A)
    [m n]=size(A);
    while 1
        pre_A=A;
        for i=1:m
            du=0;       %第m個元素的度
            for j=1:n
                if A(i,j)~=0
                    du=du+1;
                end
            end
            if du==1            %元素的度為1時刪除這個元素,其相鄰元素度減一
               A(i,:)=0;
               A(:,i)=0;
            end
        end
        if pre_A==A     %圖中沒有度為1的元素則退出
           break; 
        end
    end
    
    if sum(A(:))==0
        re=0;
    else
        re=1;
    end
end

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM