PRIM算法求最小生成树
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
xx学院
《数据结构与算法》课程设计
报告书
课程设计题目 PRIM算法求最小生成树
院系名称计算机科学与技术系
专业(班级)
姓名(学号)
指导教师
完成时间
一、问题分析和任务定义
在该部分中主要包括两个方面:问题分析和任务定义;
1 问题分析
本次课程设计是通过PRIM(普里姆)算法,实现通过任意给定网和起点,将该网所对应的所有生成树求解出来。
在实现该本设计功能之前,必须弄清以下三个问题:
1.1 关于图、网的一些基本概念
1.1.1 图图G由两个集合V和E组成,记为G=(V,E),其中V是顶点的有穷非空集合,E是V中顶点偶对的有穷集,这些顶点偶对称为边。通常,V(G)和E(G)分别表示图G的顶点集合和边集合。E(G)也可以为空集。则图G只有顶点而没有边。1.1.2 无向图对于一个图G,若边集E(G)为无向边的集合,则称该图为无向图。1.1.3 子图设有两个图G=(V,E)G’=(V’,),若V’是V的子集,即V’⊆V ,且E’是E的子集,即E’⊆E,称G’是G的子图。
1.1.4 连通图若图G中任意两个顶点都连通,则称G为连通图。
1.1.5 权和网在一个图中,每条边可以标上具有某种含义的数值,该数值称为该边的权。把边上带权的图称为网。如图1所示。
1.2 理解生成树和最小生成树之间的区别和联系
1.2.1 生成树在一个连通图G中,如果取它的全部顶点和一部分边构成一个子图G’,即:V(G’)= V(G)和E(G’)⊆E(G),若边集E(G’)中的边既将图中的所有顶点连通又不形成回路,则称子图G’是原图G的一棵生成树。
1.2.2 最小生成树图的生成树不是唯一的,把具有权最小的生成树称为图G的最小生成树,即生成树中每条边上的权值之和达到最小。如图1所示。
图1.网转化为最小生成树
1.3 理解PRIM(普里姆)算法的基本思想
1.3.1 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),其中V i∈U,V j∈(V-U),并把该边(i,j)和顶点j分别并入T的边集TE和顶点集U,如此进行下去,每次往生成树里并入一个顶点和一条边,直到n-1次后就把所有n个顶点都并入到生成树T的顶点集中,此时U=V,TE中含有n-1条边,T就是最后得到的最小生成树。可以看出,在普利姆算法中,是采用逐步增加U中的顶点,常称为“加点法”。为了实现这个算法在本设计中需要设置一个辅助数组
closedge[ ],以记录从U到V-U具有最小代价的边。当辅助数组中存在两个或两个以上的最小代价的边时,此时最小生成树的形态就不唯一,此时可以在程序中采用递归的算法思想求出每个最小生成树。
1.3.2 在PRIM算法中需要解决的两个问题
①在无向网中,当出现从一个顶点到其它顶点时,若其边上的权值相等,则可能从某一起点出发时会得出不同的最小生成树,但最小生成树的权必定都相等,此时我们应该怎样将所有的最小生成树求解出来;
②每次如何从生成树T中到T外的所有边中,找出一条最短边。例如,在第k次(1≤k ≤n-1)前,生成树T中已有k个顶点和k-1条边,此时T中到T外的所有边数为k(n-k),当然它也包括两顶点间没有直接边相联,其权值被看做常量INFINIT的边在内,从如此多的边中查找最短边,其时间复杂度为O(k(n-k)),显然是很费时的,是否有一种好的方法能够降低查找最短边的时间复杂度。
1.3.3 上述问题的解决方法
针对①中出现的问题可以通过在算法中实现,详情请看PRIM算法的基本思想;
针对②中出现的问题,通过对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)。
2 任务定义
通过以上的分析和理解,对本设计分别从以下三个方面进行分析:
2.1 输入数据的类型
在本次设计中,是对无向网进行操作,网中的顶点数、边数、顶点的编号及每条边的权值均通过键盘输入,它们的数据类型均为整型,其中,权值的范围为0~32768(即“∞”);2.2 输出数据的类型
当用户将无向网创建成功以后,就可以通过键盘任意输入一个起点值将其对应的最小生成树的生成路径及权值显示出来;
2.3测试数据
本次设计中是通过用PRIM算法求最小生成树,分别用以下三组数据进行测试:2.3.1 假定在创建无向网时只输入一个顶点,如图2所示,验证运行结果
1
图2.单一节点的图
2.3.2 假定创建的无向网如图3所示,验证运行结果
2.3.3 假定创建的无向网如图4所示,验证运行结果
二、概要设计和数据结构的选择
在本次设计中,网的定义为G=(V,E),V 表示非空顶点集,E 表示边集,其存储结构这里采用邻接矩阵的方式来存储。
1 数据类型的定义
在本设计中所涉及到的数据类型定义如下:
1.1 符号常量的定义
算法中涉及到两个符号常量,定义如下:
#define MAX 20 功能:用于表示网中最多顶点个数;
#define INFINIT 32768 功能:用于表示权的最大值,即∞。
1.2 结构体的定义
整个算法中涉及的结构体定义如下:
1.2.1 定义结构体ArcNode
功能:用于存放边的权值
typedef struct
{int adj;//权值
}ArcNode; 4 3 2 6 5 6
6
6 5 5 5 2 1
3 4
1 图3.网中存在权值相等的边 4 1
3
2 6 5 16 19 18
7 5 6 21
14
33 11 图4.网中边的权值各不相等