最小生成树问题的算法实现及复杂度分析—天津大学计算机科学与技术学院(算法设计与分析)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
算法设计与分析课程设计报告
学院计算机科学与技术
专业计算机科学与技术
年级2011
姓名XXX
学号
2013年5 月19 日
题目:最小生成树问题的算法实现及复杂度分析
摘要:该程序操作简单,具有一定的应用性。数据结构是计算机科学的算法理论基础和软件设计的技术基础,在计算机领域中有着举足轻重的作用,是计算机学科的核心课程。而最小生成树算法是算法设计与分析中的重要算法,最小生成树也是最短路径算法。最短路径的问题在现实生活中应用非常广泛,如邮递员送信、公路造价等问题。本设计以Visual Studio 2010作为开发平台,C/C++语言作为编程语言,以邻接矩阵作为存储结构,编程实现了最小生成树算法。构造最小生成树有很多算法,本文主要介绍了图的概念、图的遍历,并分析了PRIM 经典算法的算法思想,最后用这种经典算法实现了最小生成树的生成。
引言:假设要在n个城市之间建立通信联络网,则连接n个城市只需要n-1条线路。这时,自然会考虑这样一个问题,如何在节省费用的前提下建立这个通信网?自然在每两个城市之间都可以设置一条线路,而这相应的就要付出较高的经济代价。n个城市之间最多可以设置n(n-1)/2条线路,那么如何在这些可能的线路中选择n-1 条使总的代价最小呢?可以用连通网来表示n 个城市以及n个城市之间可能设置的通信线路,其中网的顶点表示城市,边表示两个城市之间的线路,赋予边的权值表示相应的代价。对于n个顶点的连通网可以建立许多不同的生成树,每一个生成树都可以是一个通信网。现在要选择这样一棵生成树,也就是使总的代价最小。这个问题便是构造连通网的最小代价生成树(简称最小生成树)的问题。最小生成树是指在所有生成树中,边上权值之和最小的生成树,另外最小生成树也可能是多个,他们之间的权值之和相等。一棵生成树的代价就是树上各边的代价之和。而实现这个运算的经典算法就是普利姆算法。
正文
普里姆(Prim)算法思想
普里姆算法则从另一个角度构造连通网的最小生成树。它的基本思想是:首先选取图中任意一个顶点 v 作为生成树的根,之后继续往生成树中添加顶点w,则在顶点 w 和顶点 v 之间必须有边,且该边上的权值应在所有和 v 相邻接的边中属最小。在一般情况下,假设图 G=(V,E) 中已落在生成树上的顶点集为U,则尚未落在生成树上的顶点集为 V-U,则从 (V-U) 顶点集中选取加入生成树的顶点 w 应满足下列条件:它和生成树上的顶点之间的边上的权值是在联接这两类顶点的所有边中权值属最小。
从上述生成树的构造过程中回还可以发现一点,即每个顶点都是通过"一条边"加入到生成树上的,因此对集合 V-U 中的每个顶点,当它和集合 U 中的顶点有一条以上的边相连时,只需要保留一条权值最小的边即可。由此,在普里姆算法中需要附设一个辅助数组 closedge,以记录从集合 U 到集合 V-U 中每个顶点当前的权值最小边。
普里姆算法构造最小生成树的过程
普里姆(Prim)算法设计:
一:定义模块:
1.头文件、新类型及固定值定义。本程序可接受的最大顶点数为20个,没有连
接的点之间,用100表示其权值。
#include
using namespace std;
#define MAX_VERTEX_NUM 20dj=QM;
cout<<"输出网的"<<<<"个顶点(限数字):"< for(i=0;i<;i++) cin>>[i]; cout<<"建立弧,请输入"<<<<"条弧的顶点和权值(v1,v2,w):"< for(k=0;k<;k++) { cin>>v1>>v2>>weight; i=LocateVex(G,v1); j=LocateVex(G,v2); if(i<0||j<0) return ERROR; [i][j].adj=weight; [j][i].adj=[i][j].adj; } return OK; } 1.最小生成树建立主程序,采用借助辅助数组的方式,对于辅助的数组,以 邻接表的选择点加入该数组,然后查找数组中权值最小,且未被选中的顶 点,然后返回该边,加入最小生成树中。 void MiniSpanTree_PRIM(MGraph G,VertexType u) { closedge dge; owcost=[k][j].adj; djvex=u; owcost=0; djvex<<" "<<[k]<<" "< ead=dge[k].adjvex; pax[time].last=[k]; x=LocateVex(G,dge[k].adjvex); y=LocateVex(G,[k]); pax[time].weight=[x][y].adj; time++; dge[k].lowcost=0; dj { owcost=[k][j].adj; dge[j].adjvex=[k]; ead<<" "< } 2.辅助生成最小生成树的函数。 int minimun(MGraph G,closedge F) { int i,min; for(i=0;i<;i++) if(F[i].lowcost!=0) break; min=i; for(i=0;i<;i++) if(F[i].lowcost!=0 &&F[i].lowcost min=i; return min; } 过程如下表:顶点标号都比图中的小1,比如v1为0,v2为1,这里首先选 择v1 从这个表格可以看到依附到v1顶点的v3的Lowcost最小为2,那么选择v3, 选择了之后我们必须要更新Lowcost数组的值,因为记录从U到V-U具有最小 代价的边,加入之后就会改变。新加入的点到其他各点的权值比原来的权值更小,