避圈法的基本思想是先把边按权由小到大排列起来,依次挑选权尽可能小的边构造生成树,即首先选取权最小边,再从其余边中选取不能与已选边构成圈的权最小的边作为添加边,依次类推,直到不存在合适的边为止.全部挑选的边与节点一起形成的图就是最小树。
例:已知六大城市:(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