普里姆算法求最小生成树.docx

上传人:b****5 文档编号:29824897 上传时间:2023-07-27 格式:DOCX 页数:16 大小:177.18KB
下载 相关 举报
普里姆算法求最小生成树.docx_第1页
第1页 / 共16页
普里姆算法求最小生成树.docx_第2页
第2页 / 共16页
普里姆算法求最小生成树.docx_第3页
第3页 / 共16页
普里姆算法求最小生成树.docx_第4页
第4页 / 共16页
普里姆算法求最小生成树.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

普里姆算法求最小生成树.docx

《普里姆算法求最小生成树.docx》由会员分享,可在线阅读,更多相关《普里姆算法求最小生成树.docx(16页珍藏版)》请在冰豆网上搜索。

普里姆算法求最小生成树.docx

普里姆算法求最小生成树

沈阳航空航天大学

 

课程设计报告

 

课程设计名称:

数据结构课程设计

课程设计题目:

Prim算法求最小生成树

 

院(系):

计算机学院

专业:

计算机科学与技术(物联网方向)

班级:

学号:

姓名:

指导教师:

 

学术诚信声明

本人声明:

所呈交的报告(含电子版及数据文件)是我个人在导师指导下独立进行设计工作及取得的研究结果。

尽我所知,除了文中特别加以标注或致谢中所罗列的内容以外,报告中不包含其他人己经发表或撰写过的研究结果,也不包含其它教育机构使用过的材料。

与我一同工作的同学对本研究所做的任何贡献均己在报告中做了明确的说明并表示了谢意。

报告资料及实验数据若有不实之处,本人愿意接受本教学环节“不及格”和“重修或重做”的评分结论并承担相关一切后果。

 

本人签名:

日期:

2015年1月15日

 

沈阳航空航天大学

课程设计任务书

课程设计名称

数据结构课程设计

专业

计算机科学与技术(物联网方向)

学生姓名

班级

学号

题目名称

Prim算法生成最小生成树

起止日期

2015

1

5

日起至

2015

1

16

日止

课设内容和要求:

在n个城市之间建立网络,只需保证连通即可,求最经济的架设方法,利用Prim算法输出n个城市之间网络图,输出n个节点的最小生成树。

其中,n个城市表示n个节点,两个城市间如果有路则用边连接,生成一个n个节点的边权树,要求键盘输入。

参考资料:

算法与数据结构,严蔚敏、?

吴伟民,清华大学出版社,2006

C程序设计,谭浩强,清华大学出版社,2010

教研室审核意见:

教研室主任签字:

指导教师(签名)

学生(签名)

2015

1

月15

 

一课程设计目的和要求

课程设计目的

(一)根据算法设计需要,掌握连通网的数据表示方法;

(二)

(三)掌握最小生成树的Prim算法;

(四)

(五)学习独立撰写报告文档。

(六)

课程设计的要求

在n个城市之间建立网络,只需保证连通即可,求最经济的架设方法,利用Prim算法输出n个城市之间网络图,输出n个节点的最小生成树。

其中,n个城市表示n个节点,两个城市间如果有路则用边连接,生成一个n个节点的边权树,要求键盘输入。

 

二实验原理分析

最小生成树的定义

一个有n个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有n个结点,并且有保持图连通的最少的边。

最小生成树可以用(克鲁斯卡尔)算法或(普里姆)算法求出。

(1).最小生成树的概述

(2).

在一给定的G=(V,E)中,(u,v)代表连接顶点u与顶点v的边(即),而w(u,v)代表此的权重,若存在T为E的(即)且为无循环图,使得w(T)最小,则此T为G的最小生成树。

 

最小生成树其实是最小权重生成树的简称。

(3).最小生成树的分析

(4).

构造最小生成树可以用多种算法。

其中多数算法利用了最小生成树的下面一种简称为MST的性质:

假设N=(V,{E})是一个连通网,U是顶点集V的一个非空子集。

若(u,v)是一条具有最小权值(代价)的边,其中u∈U,v∈V-U,则必存在一棵包含边的最小生成树。

Prim算法的基本思想

假设G=(V,E)是一个具有n个顶点的连通网,T=(U,TE)是G的最小生成树,其中U是T的顶点集,TE是T的边集,U和TE的初值均为空集。

算法开始时,首先从V中任取一个顶点(假定取V0),将它并入U中,此时U={V0},然后只要U是V的真子集,就从那些其一个端点已在T中,另一个端点仍在T外的所有边中,找一条最短(即权值最小)边,假定为(i,j),其中Vi∈U,Vj∈(V-U),并把该边(i,j)和顶点j分别并入T的边集TE和顶点集U,如此进行下去,每次往生成树里并入一个顶点和一条边,直到n-1次后就把所有n个顶点都并入到生成树T的顶点集中,此时U=V,TE中含有n-1条边,T就是最后得到的最小生成树。

可以看出,在普利姆算法中,是采用逐步增加U中的顶点,常称为“加点法”。

为了实现这个算法在本设计中需要设置一个辅助数组closedge[],以记录从U到V-U具有最小代价的边。

当辅助数组中存在两个或两个以上的最小代价的边时,此时最小生成树的形态就不唯一,此时可以在程序中采用递归的算法思想求出每个最小生成树。

(1).在prim算法中要解决两个问题

(2).

1)在无向网中,当从一个顶点到其他顶点时,若其边上的权值相等,则可能从某一起点出发时,会得到不同的生成树,但最小生成树的权值必定相等,此时我们应该如何把所有的最小生成树求解出来;

2)

3)每次如何从生成树T中到T外的所有边中,找出一条权值最小的边。

例如,在第k次(1≤k≤n-1)前,生成树T中已有k个顶点和k-1条边,此时T中到T外的所有边数为k(n-k),当然它也包括两顶点间没有直接边相连,其权值被看作常量的边在内,从如此多的边中找出最短的边,其时间复杂度0(k(n-k)),是很费时间的,是否有好的方法能够降低查找最短边的时间复杂度。

4)

(3).上述问题的解决方法

(4).

针对1)中出现的问题,可以通过算法来实现,详情请看Prim算法的概述;

针对2)中出现的问题,通过对Prim算法的分析,可以使查找最短边的时间复杂度降低到O(n-k)。

具体方法是假定在进行第k次前已经保留着从T中到T外的每一顶点(共n-k个顶点)的各一条最短边,进行第k次时,首先从这n-k条最短边中,找出一条最最短的边,它就是从T中到T外的所有边中的最短边,假设为(i,j),此步需进行n-k次比较;然后把边(i,j)和顶点j分别并入T中的边集TE和顶点集U中,此时T外只有n-(k+1)个顶点,对于其中的每个顶点t,若(j,t)边上的权值小于已保留的从原T中到顶点t的最短边的权值,则用(j,t)修改之,使从T中到T外顶点t的最短边为(j,t),否则原有最短边保持不变,这样,就把第k次后从T中到T外每一顶点t的各一条最短边都保留下来了,为进行第k+1次运算做好了准备,此步需进行n-k-1次比较。

所以,利用此方法求第k次的最短边共需比较2(n-k)-1次,即时间复杂度为O(n-k)。

三概要分析和设计

概要分析

通过对上述算法的分析,将从以下三方面来进行分析:

(1).输入数据的类型

(2).

在本次设计中,是对无向图进行操作,网中的顶点数,边数,顶点的编号及每条边的权值都是通过键盘输入的,他们的数据类型均为整型,其中,权值的范围为0~32768(即“∞”);

(3).输出数据的类型

(4).

当用户将无向图创建成功以后,就可以通过键盘任意输入一个起点值将其对应的最小生成树的生成路径及其权值显示出来;

(5).测试数据

(6).

本次设计中是通过用Prim算法求最小生成树,分别用以下三组数据进行测试:

(一)假设在创建无向图时,只输入一个顶点,如图1所示,验证运行结果;

(二)

 

A

 

图1.单一节点的无向图

(三)假设创建的无向图如图2所示,验证运行结果;

(四)

图2.网中存在权值相等的边

(五)假设创建的无向图如图3所示,验证结果;

(六)

 

图3,网中的权值各不相等

 

概要设计

在本次设计中,网的定义为G=(V,E),V表示非空顶点集,E表示边集,其存储结构这里采用邻接矩阵的方式来存储。

1数据类型的定义在本设计中所涉及到的数据类型定义如下:

(1).符号常量的定义

(2).

算法中涉及到两个符号常量,定义如下:

#defineMAX20功能:

用于表示网中最多顶点个数;

#defineINFINIT32768功能:

用于表示权的最大值,即∞。

(3).结构体的定义

(4).

整个算法中涉及的结构体定义如下:

✓定义结构体ArcNode

功能:

用于存放边的权值

typedefstruct

{

intadj;

开始

输入ch,用于判断是否创建无向网

Ch=“Y”

结束

输入起点st

1.调用create()函数

2.调用display()函数

Flog=0

st=0

3.调用prim()函数

4.调用minium()函数

程图

上述流程图反映了整个算法中各个子函数之间的嵌套调用,从主函数开始顺序往下执行,首先调用creat()函数创建无向网并采用邻接矩阵的方式来存储;然后将该网对应的邻接矩阵通过调用display()函数输出;最后调用prim()函数求出该网所对应的最小生成树,并且在prim()函数中通过嵌套调用Minium()函数求出辅助数组close[]中权值最小的边,从而完成了本设计的要求。

四测试结果

该部分是对前面任务定义中的测试数据进行验证和分析:

4.1实验一

4.2

只含一个顶点的无向图。

图5.只含一个顶点的无向图

4.3实验二

4.4

假定创建的无向网的顶点个数>1,并且网中有些边的权值相等。

图7.运行结果

分析:

在上述创建的无向网中,有些顶点之间没有边相连接,所以在邻接矩阵中用∞表示,由于是以顶点1作为起点生成最小生成树,所以上述运行结果对应的生成树如图7所示。

实验三

假定创建的无向网的顶点个数>1,并且网中有些边的权值不相等。

运行结果如下:

参考文献

(1).吴玉蓉,数据结构(C语言版),中国水利水电出版社,2008年;

(2).

(3).徐孝凯,数据结构实用教程,清华大学出版社,2005年7月;

(4).

(5).谭浩强,C语言程序设计教程,高等教育出版社,2004年5月。

(6).

 

附录(关键部分程序清单)

#include""

#include""

#include""

#include""

#include""

#defineMAX20dj=0;

else

G->arcs[i][j].adj=INFINIT;

printf("请输入网中的顶点编号:

");dj=weight;

G->arcs[j][i].adj=weight;

}

return(G);

}

}

 

intMinium(AdjMatrix*G,Nodeclose[])owcost

=0)

{

min=close[i].lowcost;

k=i;

}

returnk;owcost=0;djvex=u;

close[i].lowcost=G->arcs[k][i].adj;

}

for(j=1;j<=G->vexnum-1;j++)owcost;owcost;owcost);owcost=0;dj

{

close[i].lowcost=G->arcs[k0][i].adj;

close[i].adjvex=v0;

}

}

printf("\n最小生成树中的顶点序列为:

[");

for(i=0;ivexnum;i++)

printf("%d",p->vexs[i]);

printf("]\n");

printf("\n最小生成树的权值之和为:

%d\n",s);

}

 

voiddisplay(AdjMatrix*G)dj==INFINIT)

printf("\t∞");

else

printf("\t%d",G->arcs[i][j].adj);

printf("\n");

}

for(i=0;ivexnum;i++)

printf("─────");

printf("\n");

}

 

voidmain()//主函数

{

charch;

intst;

AdjMatrix*G,*p;

p=(AdjMatrix*)malloc(sizeof(AdjMatrix));

printf("********************************************************************************\n");

printf("普里姆最小生成树算法!

\n");

printf("\n********************************************************************************\n");

printf("设计者:

李浩渊\n");

printf("班级:

班\n");

printf("指导老师:

范纯龙老师\n");

printf("设计时间:

2015年1月15日\n");

printf("\n********************************************************************************");

printf("\n*******************若创建无向网请输入'Y',否则按任意键!

**************************\n");

scanf("%c",&ch);

while

(1)

{

if(ch=='Y'||ch=='y')

{

G=creat(p);

if(flag==0)

{

printf("\n************该无向网所对应的邻接矩阵如下***********\n");

display(G);

printf("请输入起点:

");

scanf("%d",&st);

while

(1)

{

if(st==0)

break;

else

if(st>G->vexnum)

printf("-------------------------输入起点有错,请重新输入!

------------------------------\n");

else

{

printf("----------------利用普里姆算法从起点%d出发,最小生成树的路径如下--------------\n\n",st);

printf("\n*****************************************************\n");

printf("<起点->终点>权值\n\n");

prim(G,st);

printf("\n*************************************************\n");

}

printf("请继续输入起点,否则输入0退出!

");

scanf("%d",&st);

}

}

printf("\n*****************继续创建无向网请输入'Y',否则按任意键!

**************************");

scanf("%c",&ch);

flag=0;

}

else

break;

}

}

 

课程设计总结和体会:

在整个课程设计的过程中,首先,应该根据课题的要求对题意进行分析,将所遇到的问题进行归纳和总结,在本设计中,题意要求对给定的网和起点,用PRIM算法的基本思想求解出所有的最小生成树,我们应该了解关于网的一些基本概念和生成树与最小生成树之间有何区别和联系,主要是要明确的理解PRIM算法的基本思想。

其次,针对出现的问题查找相关资料将其解决,主要应该查找有关PRIM算法基本思想方面的详细介绍,当所有的问题得到解决后,对本设计应该有个整体的思路并通过编写各个函数模块去实现课题的功能;最后,将编写的源程序代码在计算机上调试运行,直至调试成功。

本次课程设计,让我对所学的知识有了一次综合运用的机会,通过实践,提高了自己在分析问题、解决问题和编写算法方面的能力,从而对所学的知识有了更加深刻的理解和掌握,受益匪浅。

希望以后学校能多提供这样的机会给我们锻炼,使我们能够为学所用,真正增长我们的才干。

 

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 人文社科 > 哲学历史

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

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