避圈法的基本思想是先把边按权由小到大排列起来,依次挑选权尽可能小的边构造生成树,即首先选取权最小边,再从其余边中选取不能与已选边构成圈的权最小的边作为添加边,依次类推,直到不存在合适的边为止.全部挑选的边与节点一起形成的图就是最小树。
例:已知六大城市:(Pe),(N),(Pa),(L),(T),(M),它们之间的交通网络数据如下表所示,求最小支撑树。
城市 | Pe | T | Pa | M | N | L |
Pe | × | 13 | 51 | 77 | 68 | 50 |
T | 13 | × | 60 | 70 | 67 | 59 |
Pa | 51 | 60 | × | 57 | 36 | 2 |
M | 77 | 70 | 57 | × | 20 | 55 |
N | 68 | 67 | 36 | 20 | × | 34 |
L | 50 | 59 | 2 | 55 | 34 | × |
程序代码:
W=[0 13 51 77 68 50
13 0 60 70 67 59
51 60 0 57 36 2
77 70 57 0 20 55
68 67 36 20 0 34
50 59 2 55 34 0];
n=length(W);
T=zeros(n);
W2=W;
for i=1:n
for j=1:n
if W(i,j)==inf
W2(i,j)=0;
end
end
end
m=((nnz(W2))/2);
j=0;
for i=1:m
if j<(n-1)
minw=inf;
a=0;
b=0;
for k=1:n
for s=(k+1):n
if W(k,s)<=minw
minw=W(k,s);
a=k;
b=s;
end
end
end
T(a,b)=W(a,b);
T(b,a)=W(a,b);
f=0;
P=zeros(2,m);
y=0;
for i=1:n
for v=(i+1):n
if T(i,v)~=0
y=y+1;
P(1,y)=i;
P(2,y)=v;
end
end
end
for y=1:m
if P(1,y)<P(2,y)
for s=(y+1):m
if P(1,s)==P(2,y)
P(1,s)=P(1,y);
elseif P(2,s)==P(2,y)
P(2,s)=P(1,y);
end
end
P(2,y)=P(1,y);
elseif P(2,y)<P(1,y)
for s=(y+1):m
if P(1,s)==P(1,y)
P(1,s)=P(2,y);
elseif P(2,s)==P(1,y)
P(2,s)=P(2,y);
end
end
elseif (P(1,y)+P(2,y))~=0
f=1;
break;
end
end
if f==1
T(a,b)=0;
T(b,a)=0;
else
j=j+1;
end
W(a,b)=inf;
else
MST=T;
dianshu=n
node=input('输入节点坐标:')
fprintf('图的最小生成树的权邻接矩阵为:');
for i = 1:n
for j = 1:n
if MST(i,j)==inf
MST(i,j)=0;
end
end
end
MST
gplot(MST,node,'r-d')
weight=sum(sum(MST))/2
break;
end
end
if j<(n-1)
fprintf('该图没有最小生成树!')
end
运行结果:
>> Kruskal
dianshu =
6
输入节点坐标:[-2,0;-1,2;1,3;2,-1;1,-4;-1,-2]
node =
-2 0
-1 2
1 3
2 -1
1 -4
-1 -2
图的最小生成树的权邻接矩阵为:
MST =
0 13 0 0 0 50
13 0 0 0 0 0
0 0 0 0 0 2
0 0 0 0 20 0
0 0 0 20 0 34
50 0 2 0 34 0
weight =
119