ImageVerifierCode 换一换
格式:DOCX , 页数:19 ,大小:100.83KB ,
资源ID:3536501      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/3536501.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(图论论文最小生成树算法城市高速公路问题中的应用.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

图论论文最小生成树算法城市高速公路问题中的应用.docx

1、图论论文最小生成树算法城市高速公路问题中的应用XXXX研究生堂下考试答卷2012-2013学年第 1 学期2012年 12 月 18 日最小生成树在城市高速公路问题中的应用摘 要: 城市高速公路问题就是以最短高速路程连接一组城市的问题,在城市规划和建设中应用广泛。本文以最小生成树在城市高速公路问题中的应用为例,利用最小生成树的三种算法的分析和研究,阐明了最小生成树在最优化方面的作用。关键词:城市高速公路问题 Prim算法 Kruskal算法 简易算法一 引言图论是数学的一个分支。它以图为研究对象。在图论的课程体系中,图结构是一种非常重要的非线性数据结构。带权图的最小生成树尤其被广泛应用在解决工

2、程技术及科学管理等各个领域的最优化问题中。二 背景知识1 图和树:图论中的图是由若干给定的点及连接两点的线所构成的图形,这种图形通常用来描述某些事物之间的某种特定关系,用点代表事物,用连接两点的线表示相应两个事物间具有这种关系。树是五圈连通无向图,如果树T的节点数为n,那么树的边数为n-1。2 生成树:连通图 G 上的一个子图,该子图连通,无回路且包含图G 的所有节点,称为连通图的极小连通子图。一个连通图可以有多棵不同的生成树。3 最小生成树:对一个带权连通图,也有多可不同的生成树。由于该图是带权图,各边的权值不一定相等,因此这些生成树的各边权值之和也不一定相同,其中权值最小的生成树被称为该带

3、权连通图的最小生成树。4 高速公路问题:假设有 N 个城市,第 i 个城市的位置笛卡尔坐标为 (xi,yi),每条公路可以连接两个城市。目前原有的公路有m 条,但是不能实现所有城市之间的连通,因此需要继续修建公路,在费用最低的原则下,实现 N 个城市的连通,还需要修建哪些条公路。由于修路的费用与公路的长短是成正比的,所以这个问题就可以转化成求修建哪几条公路能够实现所有城市的连通,同时满足所修公路总长最短。三 最小生成树的求解方法构造最小生成树可以有多种算法。大多数图论教材中介绍了其中的两种算法 Prim 算法和 Kruskal 算法,本文另介绍一种简易算法来实现最小生成树的构造。1 Prim

4、算法思想:普里姆算法通过逐个往生成树上添加顶点来构造连通网的最小生成树。算法具体步骤:(1) 开始:选取连通网中的任意一个顶点添加到最小生成树中。(2) 重复执行以下操作:1) 连通网的顶点集合分成两个部分:已经添加到最小生成树中的顶点集合和尚未添加到最小生成树中的顶点集合;2) 找出所有连通这两个集合中顶点的边;3) 从中选取一条权值最小的边添加到生成树中,同时将与这条边相连的顶点也添加到生成树中。(3)结束:所有的顶点都被添加到最小生成树中。2 Kruskal 算法思想:通过逐个往生成树上添加边来构造连通网的最小生成树。算法具体步骤:(1) 将连通网中的所有顶点添加到最小生成树中,构造一个

5、森林;(2) 将各边按照权值从小到大排序;(3) 按照排好的顺序向生成树中添加不使森林中产生回路的边 (若构成回路则不添加,继续考察下一条边)。直至该森林变成一棵树为止。3 简易算法思想:通过逐个从连通网中删除边来构造最小生成树。算法具体步骤:(1) 将连通网中各边按照权值从大到小排序;(2) 按照排好的顺序从连通网中删除权值最大的边,条件是使删除该边后的子图仍然保持连通(若删除后子图不连通则改边保留,继续删除下一条边)。直至子图中任何一条边都不能删除 (即删除任意一条边都会造成该子图不连通)为止。4 三种算法的比较(1) 普里姆算法:主要是对顶点进行操作;采用邻接矩阵作为存储结构,在行过程中

6、对连通网中的每一个顶点都考察到了,因此普里姆算法的时间复杂度为(n 为连通网中顶点的个数)。普里姆算法适用于求边稠密的连通网的最小生成树。(2) 克鲁斯卡尔算法:主要是对边进行操作,时间复杂度主要取决于对边按照权值进行排序的时间,边的个数为e,排序的时间复杂度可以做到O (eloge),因此算法的时间复杂度为 O(eloge)。克鲁斯卡尔算法适用于求边稀疏的连通网的最小生成树。(3) 简易算法:主要是对边进行操作,时间复杂度主要取决于对边按照权值进行排序的时间,边的个数为e,排序的时间复杂度可以做到 O (eloge),因此算法的时间复杂度为 O(eloge)。该算法适用于求边稀疏的连通网的最

7、小生成树。四 应用利用最小生成树来解决高速公路问题,将高速公路问题中的城市看做图中的顶点,城市之间修建的道路看做图中顶点之间的边,城市之间所修修建的公路的长度看做是图中个边上的权值。这样我们就把高速公路问题转换成了求一个有向连通网的最小生成树问题。此时假设城市个数为6,分别为a,b,c,d,e,f。并设其对应城市之间的公路距离权值及初始状态的连通无向图如下所示:边(a,b)(a,c)(a,d)(b,c)(b,e) (c,d)(c,e)(c,f)(d,f)(e,f)权值61553564261 简易算法来求解最小生成树(1) 实现步骤:从权值最大的边开始进行删除 (e,f),(c,e) ,(a,b

8、),(a,d)被删除后都没有破坏连通性,所以这些边可以从图中删除,得下图:当删除第五条边(b,c)时,造成了图的连通性的破坏,所以该条边不能被删除必须保留。下图为最终构造好的最小生成树:(2) 算法实现:1)连通网的存储结构表示城市高速公路网络的无向连通网采用邻接矩阵的存储方式进行存储。由于需要区分已经存在的公路和需要修建的公路,所以在每条边上增加一个标志位,同时为了给所有的边排序,因此单独建立一个表示边信息的结构体数组结构。具体实现如下:typedef char TownType; typedef float RoadType;typedef struct int n; /*图的顶点个数 *

9、/int m; /* 图的边个数 */TownType towns MAXVEX ; /* 顶点信息 */RoadType roadsMAXVEXMAXVEX ;/*边信息 */ GraphMatrix;typedef struct int start_town, stop_town; /* 边的起点和终点 */RoadType weight; /* 边的权 */enum EXIST,UNEXIST ex;/*区别已经建好的公路和未修建的公路 */ Edge;Edge mst 50 ;2) 判断图的连通性函数判断无向图的的连通性有很多方法,这里采用的是通过对图进行深度优先搜索,统计遍历过的顶点

10、个数,如果顶点个数比图中顶点个数少,说明该图不连通,相反说明该图是连通图。具体实现如下:void dfsMatrix (GraphMatrix GM, int i, int n , int &visited ) int j;printf “(%d”,i) ;visited i =1;for (int j=0;jn;j+)if ( GM i j ! =0 & GM i j ! =MaxValue& ! visited j)dfsMatrix (GM,j,n) ;遍历结束后可以通过统计 visited 数组中的值为 1 的元素的个数 v 来确定访问过的结点个数,如果 vn 说明该无向图不连通,反之

11、说明该无向图连通。GraphThrough (GraphMatrix GM)for (i=0;in;i+) visited i =0dfsMatrix (GM, 0, n , visited) ;for (i=0;in;i+)if ( visited i =1) num+;if (num=n) return 1;else return 0;3) 对权值进行由大到小排序由于整个算法的时间复杂度主要取决于排序算法的效率高低,因此在这里我们采用的是快速排序算法QSort (Edge&mst, int i, int j ),排序的时间复杂度可以做到O (eloge)。具体算法实现就不再赘述。4) 简易

12、算法的主体部分int easy (GraphMatrix &GM , Edge mst )int i, j, num = 0, th,weight;for (i=0;iGM.m;i+)if (mst i .ex=UNEXIST)weight=GM. roads start_town stop_town ;GM. roads start_town stop_town =0;th=GraphThrough (GM) ;if (th=1) continue;else GM. roads start_town stop_town =weight;2 Prim算法求解最小生成树(1)实现步骤:从节点a开

13、始,依次添加节点c,f,d,b,e,并依次添加对应的边,各个步骤如下图所示:(2) 算法实现:#include#include#include#define INFINITY 1000#define max_name 50#define max_vertex_num 50typedef char vertexmax_name;/顶点名字串typedef int adjMatrixmax_vertex_nummax_vertex_num;/邻接距阵typedef struct vertex adjvex; /邻接矩阵 int lowcost; /权值closemax_vertex_num;/定义

14、一个结构以便在后面closedge 使用typedef struct/定义图 vertex vexsmax_vertex_num; /顶点集 adjMatrix arcs; /边 int vexnum,arcnum;/点个数,边个数MGraph;int LocateVex(MGraph G,vertex u)/若G中存在顶点u,则返回该点在图中位置;否则返回其他信息; int i; for(i=0;iG.vexnum;+i) if(strcmp(u,G.vexsi)=0) return i; return 1;void CreateGraph(MGraph &G) int i,j,k,w; v

15、ertex v1,v2; printf(输入无向图顶点数和边数: n); scanf(%d %d,&G.vexnum,&G.arcnum); printf(输入各顶点的值:n, G.vexnum); for(i=0;iG.vexnum;+i) /构造顶点集 scanf(%s,&G.vexsi); for(i=0;iG.vexnum;+i) /初始化邻接方阵 for(j=0;jG.vexnum;+j) G.arcsij=INFINITY; printf(输入一条边依附的顶点及权值: n,G.arcnum);/输入一条边依附的顶点及权值 for(k=0;kG.arcnum;+k) scanf(%s

16、%s%d,v1,v2,&w); i=LocateVex(G,v1);/v1在图中位置 j=LocateVex(G,v2);/v2在图中位置 G.arcsij=G.arcsji=w; /置于对称弧 int minimum(close c,MGraph G)/求出下一个节点 第k个顶点 int i=0,j,k,min; min=INFINITY; /初始化 k=-1; for(j=0;j=G.vexnum;j+)/求最小 if(cj.lowcost0) min=cj.lowcost; k=j; return k;void PRIM(MGraph G,vertex u) int i,j,k=0; c

17、lose closedge;/一个结构 bool isbreak=false; k=LocateVex(G,u);/u在图中位置 返回G.vexsi中下标 for(j=0;j=G.vexnum;+j) /辅助数组初始化 closedge从O 开始 if(j!=k)/没有自己到自己的 closedgek.lowcost=0; strcpy(closedgej.adjvex,u); closedgej.lowcost=G.arcskj;/列 int flag1000; flag0=0; int count=1; for(i=1;iG.vexnum;+i) k=minimum(closedge,G)

18、; if(k=-1) isbreak=true; break; printf(%s-%s%dn,closedgek.adjvex,G.vexsk,G.arcskLocateVex(G,closedgek.adjvex); /输出生成树的边 closedgek.lowcost=0; / 第k个顶点并入U集 flagcount=k; count+; for(j=0;jG.vexnum;+j) if(G.arcskjclosedgej.lowcost)/新顶点并入U后重新选择最小边 strcpy(closedgej.adjvex,G.vexsk); closedgej.lowcost=G.arcsk

19、j; if(isbreak) printf(此图不连通,无最小支撑树 !n访问过的点为:n);for(i=0;icount;i+) printf(%s ,G.vexsflagi);printf(n); void main() MGraph G; CreateGraph(G); printf(最小生成树的各条边为: n); PRIM(G,G.vexs0); 3 Kruskal算法求解最小生成树(1)实现步骤:依次添加边(a,c), (d,f), (b,e), (c,f), (b,c),并依次添加对应节点,各个步骤结果如下图:(2) 算法实现:#include#include#define M 2

20、0#define MAX 20typedef struct /构造边 int begin; int end; int weight; /权值edge;typedef struct int adj; int weight;AdjMatrixMAXMAX;typedef struct AdjMatrix arc; int vexnum, arcnum; /顶点数和边数MGraph;void CreatGraph(MGraph *); /函数申明 构造图void sort(edge* ,MGraph *); /函数申明 对边的排序void MiniSpanTree(MGraph *); /最小生成树

21、int Find(int *, int ); void Swapn(edge *, int, int); /交换两条边的权值和它们的起点和终点 void CreatGraph(MGraph *G) /构件图G int i, j,n, m; printf(请输入图的顶点数和边数:); scanf(%d %d,&G-vexnum,&G-arcnum); for (i = 1; i vexnum; i+) /初始化图 for ( j = 1; j vexnum; j+) G-arcij.adj = G-arcji.adj = 0; for ( i = 1; i arcnum; i+) /输入边和权值

22、 printf(n请输入边的起始点和终点:); scanf(%d %d,&n,&m); while(n G-vexnum | m G-vexnum) printf( n);printf( n); printf(输入的数字不符合要求 请重新输入:); scanf(%d%d,&n,&m); G-arcnm.adj = G-arcmn.adj = 1; getchar(); printf(n请输入%d与%d之间的权值: , n, m); scanf(%d,&G-arcnm.weight); /输入权值 void sort(edge edges,MGraph *G) /对权值进行排序 int i, j

23、; for ( i = 1; i arcnum; i+) for ( j = i + 1; j arcnum; j+) if (edgesi.weight edgesj.weight) Swapn(edges, i, j); printf( n); printf( n); printf( n); printf( 权 从 小 到 大 排 序 之 后 为:n); printf(n); printf( 起点 终点 权n); for (i = 1; i arcnum; i+) printf( %dn, edgesi.begin, edgesi.end, edgesi.weight); void Swa

24、pn(edge *edges,int i, int j) /交换权值 以及头和尾 int temp; temp = edgesi.begin; edgesi.begin = edgesj.begin; edgesj.begin = temp; temp = edgesi.end; edgesi.end = edgesj.end; edgesj.end = temp; temp = edgesi.weight; edgesi.weight = edgesj.weight; edgesj.weight = temp; void MiniSpanTree(MGraph *G)/生成最小生成树 int

25、 i, j, n, m; int k = 1; int parentM; edge edgesM; for ( i = 1; i vexnum; i+) for (j = i + 1; j vexnum; j+) if (G-arcij.adj = 1) edgesk.begin = i; edgesk.end = j; edgesk.weight = G-arcij.weight; k+; sort(edges, G); for (i = 1; i arcnum; i+) parenti = 0; printf(n); printf( n); printf( n); printf( n);

26、printf( 最 小 生 成 树 为:n); printf(=n); printf( 起点 终点 权 n); for (i = 1; i arcnum; i+)/核心部分 n = Find(parent, edgesi.begin); m = Find(parent, edgesi.end); if (n != m) parentn = m; printf( %dn, edgesi.begin, edgesi.end, edgesi.weight); printf(*n); int Find(int *parent, int f)/找尾 while ( parentf 0) f = pare

27、ntf; return f; int main(void)/主函数 MGraph *G; G = (MGraph*)malloc(sizeof(MGraph); if (G = NULL) printf(memory allcation failed,goodbye); exit(1); CreatGraph(G); MiniSpanTree(G); system(pause); return 0;五 总结本文在介绍了Prim算法,Kruskal算法的同时,介绍了一种新的简易算法用来求解最小生成树,并对它们进行了一定的比较。最后以高速公路问题作为应用,分别给出了三种算法的运算步骤和算法实现。结果表明,三种算法都可以求解出最小生成树。参考文献1Ronald L Graham,Pavol Hell.On the history

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1