最近因为任务需要了解了Kruskal最小生成树(Minimum Spanning Tree)算法,算法的描述请参考Kruskal's algorithm,现成的C++代码请参考(Kruskal’s Minimum Spanning Tree using STL in C++),本文是根据上述C++代码改编而来,供广大读者们学习参考:
主程序如下:
clc;
clear;
%加载文件,第一、二列数据为顶点,一二列组合为一条边,第三列为权重
fileID = fopen('D:\matlabFile\DNMC\test.txt');
DS=textscan(fileID,'%f %f %f');
fclose(fileID);
%将数据转换为矩阵格式
D=cat(2,DS{1},DS{2});
D=cat(2,D,DS{3});
%集合顶点
Vertex=cat(1,DS{1},DS{2});
Vertex=unique(Vertex);
%统计定点的数量
Vertex_num=length(Vertex);
%按权重值对边进行排列
D_sort=sortrows(D,3);
%取出边
Edge=D_sort(:,1:2);
%统计边的数量
Edge_num=size(Edge,1);
%取出权重矩阵
Weight=D_sort(:,3);
%最小生成树的权重值总和
Mst_wt = 0;
%%%%=======生成不相交数据集
%顶点的排序,初始值都为零
global Rank_vertex;
Rank_vertex=zeros(1,Vertex_num+1);
%顶点的父级,初始值就是其本身
global Parent;
Parent=sort(randperm(Vertex_num+1));
%遍历所有的边
for i=1:Edge_num
%获得第i组顶点
u=Edge(i,1);
v=Edge(i,2);
%分别寻找u和v的父值
set_u=FindParent(u);
set_v=FindParent(v);
if set_u~=set_v
fprintf('%f---- %f\n',u-1,v-1);
%权重值相加
Mst_wt=Mst_wt+Weight(i);
%合并两个顶点
MergeUV(set_u,set_v);
end
end
FindParent函数如下:
function P=FindParent(u)
global Parent;
if u~=Parent(u)
Parent(u)=FindParent(Parent(u));
end
P=Parent(u);
MergeUV函数如下:
function M=MergeUV(set_u,set_v)
global Rank_vertex;
global Parent;
x=FindParent(set_u);
y=FindParent(set_v);
if Rank_vertex(x)>Rank_vertex(y)
Parent(y)=x;
else
Parent(x)=y;
end
if Rank_vertex(x)==Rank_vertex(y)
Rank_vertex(y)=Rank_vertex(y)+1;
end
测试数据如下,请保存为txt格式:
1 2 4
1 8 8
2 3 8
2 8 11
3 4 7
3 9 2
3 6 4
4 5 9
4 6 14
5 6 10
6 7 2
7 8 1
7 9 6
8 9 7
1 8 8
2 3 8
2 8 11
3 4 7
3 9 2
3 6 4
4 5 9
4 6 14
5 6 10
6 7 2
7 8 1
7 9 6
8 9 7