% date:2020年3月7日
% Author:Chauncy_xu
clc;
clear all;%% 避圈法求解最小生成树
G =[0,1,1,1,1;1,0,1,1,1;1,1,0,1,1;1,1,1,0,1;1,1,1,1,0];[Num,~]=size(G);%% 准备工作
Tree = zeros(Num);%生成树,也是用其邻接矩阵表达的
Num_e=((nnz(G))/2);%图的边的数目
%nnz函数可以直接返回矩阵中的非0元素个数
j =0;%用来控制最小生成树的边的数目
%% 开始
for i=1:Num_e %对所有的边进行遍历
if j<(Num-1)%算法的终止条件是边数等于定点数-1%% 步骤一:选边G(a,b)
ch=0;while ch==0
a = ceil(rand()*Num);%随机产生顶点a的位置
b = ceil(rand()*Num);%随机产生顶点b的位置
if b==a %进行修正
if a==1
b =2;else
b = b-1;
end
end
if Tree(a,b)==0
ch=1;
end
end
%% 步骤二: T = T + e(a,b)
Tree(a,b)=1;
Tree(b,a)=1;%% 步骤三:检查是否有环出现
flag =0;% 标志flag为0表示没有环出现
P = zeros(2,Num_e);%创建一个两行Num_e列的矩阵
%所有元素赋初值为0
y =0;for i=1:Num
for v=(i+1:Num)if Tree(i,v)~=0
y=y+1;
P(1,y)=i;
P(2,y)=v;
end
end
end
for y=1:Num_e
if P(1,y)<P(2,y)for k=(y+1):Num_e
if P(1,k)==P(2,y)
P(1,k)=P(1,y);
elseif P(2,k)==P(2,y)
P(2,k)=P(1,y);
end
end
P(2,y)=P(1,y);
elseif P(2,y)<P(1,y)for k=(y+1):Num_e
if P(1,k)==P(1,y)
P(1,k)=P(2,y);
elseif P(2,k)==P(1,y)
P(2,k)=P(2,y);
end
end
P(1,y)=P(2,y);
elseif (P(1,y)+P(2,y))~=0
flag =1;%出现一个环
break;
end
end
if flag==1
Tree(a,b)=0;
Tree(b,a)=0;else
j=j+1;
end
else%如果条件|E|=|V|-1成立
Tree %#ok<NOPTS>break
end
end