数学建模-最小生成树-kruskal算法及各种代码

上传人:飞****9 文档编号:143132924 上传时间:2020-08-26 格式:DOC 页数:20 大小:327.51KB
返回 下载 相关 举报
数学建模-最小生成树-kruskal算法及各种代码_第1页
第1页 / 共20页
数学建模-最小生成树-kruskal算法及各种代码_第2页
第2页 / 共20页
数学建模-最小生成树-kruskal算法及各种代码_第3页
第3页 / 共20页
数学建模-最小生成树-kruskal算法及各种代码_第4页
第4页 / 共20页
数学建模-最小生成树-kruskal算法及各种代码_第5页
第5页 / 共20页
点击查看更多>>
资源描述

《数学建模-最小生成树-kruskal算法及各种代码》由会员分享,可在线阅读,更多相关《数学建模-最小生成树-kruskal算法及各种代码(20页珍藏版)》请在金锄头文库上搜索。

1、kruskal算法及代码-含伪代码、c代码、matlab、pascal等代码K r u s k a l算法每次选择n- 1条边,所使用的贪婪准则是:从剩下的边中选择一条不会产生环路的具有最小耗费的边加入已选择的边的集合中。注意到所选取的边若产生环路则不可能形成一棵生成树。K r u s k a l算法分e 步,其中e 是网络中边的数目。按耗费递增的顺序来考虑这e 条边,每次考虑一条边。当考虑某条边时,若将其加入到已选边的集合中会出现环路,则将其抛弃,否则,将它选入。目录Kruskal算法 1. 算法定义 2. 举例描述Kruskal算法的代码实现 1. 伪代码 2. C代码实现 3. matl

2、ab代码实现 4. pascal代码实现Kruskal算法 1. 算法定义 2. 举例描述Kruskal算法的代码实现 1. 伪代码 2. C代码实现 3. matlab代码实现 4. pascal代码实现算法定义克鲁斯卡尔算法 假设 WN=(V,E) 是一个含有 n 个顶点的连通网,则按照克鲁斯卡尔算法构造最小生成树的过程为:先构造一个只含 n 个顶点,而边集为空的子图,若将该子图中各个顶点看成是各棵树上的根结点,则它是一个含有 n 棵树的一个森林。之后,从网的边集 E 中选取一条权值最小的边,若该条边的两个顶点分属不同的树,则将其加入子图,也就是说,将这两个顶点分别所在的两棵树合成一棵树;

3、反之,若该条边的两个顶点已落在同一棵树上,则不可取,而应该取下一条权值最小的边再试之。依次类推,直至森林中只有一棵树,也即子图中含有 n-1条边为止。 举例描述克鲁斯卡尔算法(Kruskals algorithm)是两个经典的最小生成树算法的较为简单理解的一个。这里面充分体现了贪心算法的精髓。大致的流程可以用一个图来表示。这里的图的选择借用了Wikipedia上的那个。非常清晰且直观。 首先第一步,我们有一张图,有若干点和边 如下图所示: 第一步我们要做的事情就是将所有的边的长度排序,用排序的结果作为我们选择边的依据。这里再次体现了贪心算法的思想。资源排序,对局部最优的资源进行选择。 排序完成

4、后,我们率先选择了边AD。这样我们的图就变成了 第二步,在剩下的变中寻找。我们找到了CE。这里边的权重也是5 依次类推我们找到了6,7,7。完成之后,图变成了这个样子。 . 下一步就是关键了。下面选择那条边呢? BC或者EF吗?都不是,尽管现在长度为8的边是最小的未选择的边。但是现在他们已经连通了(对于BC可以通过CE,EB来连接,类似的EF可以通过EB,BA,AD,DF来接连)。所以我们不需要选择他们。类似的BD也已经连通了(这里上图的连通线用红色表示了)。 最后就剩下EG和FG了。当然我们选择了EG。最后成功的图就是下图: . 到这里所有的边点都已经连通了,一个最小生成树构建完成。 编辑本

5、段Kruskal算法的代码实现伪代码MST-KRUSKAL(G,w) C代码实现/* Kruskal.c Copyright (c) 2002,2006 by ctu_85 All Rights Reserved. */ /* I am sorry to say that the situation of unconnected graph is not concerned */ #include stdio.h #define maxver 10 #define maxright 100 int Gmaxvermaxver,record=0,touchedmaxvermaxver; int

6、circle=0; int FindCircle(int,int,int,int); int main() int pathmaxver2,usedmaxvermaxver; int i,j,k,t,min=maxright,exsit=0; int v1,v2,num,temp,status=0; restart: printf(Please enter the number of vertex(s) in the graph:n); scanf(%d,&num); if(nummaxver|num0) printf(Error!Please reinput!n); goto restart

7、; for(j=0;jnum;j+) for(k=0;knum;k+) if(j=k) Gjk=maxright; usedjk=1; touchedjk=0; else if(j=maxright|temp-1) printf(Invalid input!n); goto re; if(temp=-1) temp=maxright; Gjk=Gkj=temp; usedjk=usedkj=0; touchedjk=touchedkj=0; for(j=0;jnum;j+) pathj0=0; pathj1=0; for(j=0;jnum;j+) status=0; for(k=0;knum;

8、k+) if(Gjkmaxright) status=1; break; if(status=0) break; for(i=0;inum-1&status;i+) for(j=0;jnum;j+) for(k=0;knum;k+) if(Gjkmin&!usedjk) v1=j; v2=k; min=Gjk; if(!usedv1v2) usedv1v2=1; usedv2v1=1; touchedv1v2=1; touchedv2v1=1; path0=v1; path1=v2; for(t=0;trecord;t+) FindCircle(patht0,patht0,num,patht0

9、); if(circle) /*if a circle exsits,roll back*/ circle=0; i-; exsit=0; touchedv1v2=0; touchedv2v1=0; min=maxright; else record+; min=maxright; if(!status) printf(We cannot deal with it because the graph is not connected!n); else for(i=0;inum-1;i+) printf(Path %d:vertex %d to vertex %dn,i+1,path0+1,pa

10、th1+1); return 1; int FindCircle(int start,int begin,int times,int pre) /* to judge whether a circle is produced*/ int i; for(i=0;i0); %将构成圈的边从index中除去 if i=len break; %找到符合条件的点数减一条的边,即找到一个最小支撑树 end end index=index(1:len-1); %截短index矩阵,保留前len-1项 % 结果显示 % s=sprintf(nt%st%st %st,边端点,距离,是否在最小支撑树); for i=1:count-1

展开阅读全文
相关资源
相关搜索

当前位置:首页 > IT计算机/网络 > 其它相关文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号