Kruskal最小生成树

%% matlab练习程序(Kruskal最小生成树)
% Kruskal算法类似于连通分支算法,感觉和过去实现过的连通区域标记算法非常像。
% 步骤:
% 1.对于一个图,将图的每条边提取出来从小到大进行排序。
% 2.将已排序的边依次加入到新图中,如果新图中出现了环,那么就舍弃这条边。
% 3.不断重复第二步。
% 下面两个图就是kruskal算法前后的样子。

注释:图中红色为最小生成树

clc;
clear all;
close all;

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];

[tempw] = find(G ~= 0);
g = G(tempw);
k = length(g);
[tempb,tempa] = find(G~=0);
e = [tempb,tempa];
[wa,wb] = sort(g);
E = [wa,e(wb,:)];
%% 生成树构造
A= zeros(size(G));
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

%% 绘图
[x,y] = cylinder(1,length(G(1,:)));
plot(x(1,:),y(1,:),'r*','markersize',10,'linewidth',1);
hold on 
for i = 1:length(G(1,:))
temp = ['v',int2str(i)];
text(x(1,i) +0.1,y(1,i),temp);
end
for i = 1:length(e(:,1))
plot(x(1,e(i,:)),y(1,e(i,:)),'b','linewidth',1)
end
hold on 
%绘制最小生成树
[tmpa,tmpb]=find(A ~= 0);
e = [tmpa,tmpb];
[nE,mE] = size(e);
for i = 1:nE
plot(x(1,e(i,:)),y(1,e(i,:)),'r','linewidth',2);
end

function re = huan(A)

[m,n] = size(A);

  while 1

    pre_A = A;

    for i = 1:m

      du = 0

      for j = 1:n

        if A(i,j) ~ = 0

         du = du +1; 

        end

      end  

        if du == 1
      A(i,:) = 0;
      A(:,i) = 0;
     end

    end

    if pre_A == A

      break;
    end

  end

  if sum(A(:)) == 0
    re = 0;
  else
    re =1;
  end

end

 http://www.cnblogs.com/tiandsp/category/348031.html

posted on 2014-10-26 13:44  Kermit.Li  阅读(287)  评论(0编辑  收藏  举报

导航