无向连通网的最小生成树算法[第1部分]

2024-05-15 21:32

本文主要是介绍无向连通网的最小生成树算法[第1部分],希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

摘要:求解图的最小生成树在工程管理、最优化规划等领域有广泛的应用,因此对最小生成树算法的研究具有重要的意义。本文针对图的最小生成树算法,首先对几种经典的最小生成树算法进行了总结,最后针对无向连通网的最小生成树问题,分别使用普利姆算法和克鲁斯卡尔算法进行了详细的算法原理分析与程序实现。
关键词:无向连通网;最小生成树算法;普利姆算法;克鲁斯卡尔算法
The Minimum Spanning Tree Algorithm of undirected connected network

Abstract:The minimum spanning tree of graphs is widely used in engineering management, optimization planning and other areas, so it is very important to study the minimum spanning tree algorithm. In this paper, Several classical minimum spanning tree algorithms are summarized, At the same time, a detailed algorithm analysis and program realization are carried out for the minimum spanning tree problem of undirected connected network by using the Prim algorithm and the Kruskal algorithm.
Key words:Undirected connected network;MST;Prim algorithm;Kruskal algorithm
1 引 言
求解图的最小生成树(Minimum Spanning Tree,MST)属于图论的典型应用问题。其中,连通图的最小生成树在理论研究和工程设计上均有广泛的研究和应用,因此最小生成问题从提出到理论描述,再到算法实现方式都取得了丰富的研究和应用成果。迄今为止,国内外学者就最小生成树问题,分别针对有向图和无向图提出了多种解决策略。其中,针对带权值的有向图,吴文虎等[1]提出了通过有向圈的收缩和展开求解最小生成树的策略;冯俊文[2]等提出了基于表格表示的表上作业法;对于无向图的最小生成树算法,包含Prim算法、Kruskal算法、Dijkstra最小生成树等经典的求解算法[3]。本文针对无向连通网的最小生成树问题,首先针对经典的Prim算法通过从部分最小生成树边集合扩展的角度逐步从剩余候选边集中选取最小边构造最小生成树;针对Kruskal算法可能的环路问题,通过使用并查集[4-5]来对所选的边进行连通分量的判断,同时对所选边集合进行路径压缩提高下一次查询效率。最后给出了详细的算法设计流程和实例验证。
2 算法描述
最小生成树问题在实际的工程管理、最优化规划等方面有实际的应用价值,例如交通路网的规划、旅行路线规划、通信网络设计、故障诊断[6-7]等。因此在基于图论的应用问题中,通常需要对带权值的无向连通图求最小生成。在求无向连通网的最小生成树时,需要预先构造一个带权值的无向连通图并用邻接矩阵表示图的存储结构,无向连通网和邻接矩阵表示分别如下所示(其中*表示距离为无穷)。
这里写图片描述
在最小生成树的求解算法中,Prim算法和kruskal算法使用最为广泛,本文利用Prim算法和Kruskal算法思想进行详细的程序设计与求解验证。
2.1 Prim算法
这里写图片描述
这里写图片描述
2.2 Kruskal算法
这里写图片描述
3 算法实现描述
3.1 Prim算法实现描述
根据Prim算法的思想和伪代码,在程序开始时需要给定一个连通网并给出一个初始顶点。接着从最小生成树边集合扩展的角度,从剩余结点和边中选择出权值最小的边,分别加入生成树的顶点集合和边集合。由于对于连通网其生成树总是存在的,因此根据生成树的性质,对于N个结点的连通网,需要N-1条边是的任意两个结点之间相互连通,那么算法结束的条件满足经过N-1此迭代,并在每一次迭代中选择出权值最小的边。如果在任意一次迭代过程中,不存在由已经加入生成树和剩余顶点集之间取值最小的边,则该连通网的输入数据存在错误导致图不连通。
为了方便实现边信息的表示,定义一个结构体类型的边结点edgeNode,该结点中存储边的起始顶点from、终点顶点to以及边的权值cost,同时定义邻接矩阵AdjMatrix和边集合数组edgeSet。
这里写图片描述
这里写图片描述
为了表述普利姆算法边和顶点的加入过程,使用流程图[8]来表示整个程序各实现步骤之间的逻辑关系,普利姆算法程序运行流程图如下:
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
3.2 Kruakal算法实现描述
根据Kruskal算法的思想和伪代码,程序在开始的时候需要对连通网中的边按照权值排序,接着从边集合扩展的角度,从剩余边集中选择最小的边,若所选边加入后不构成环路,则分别将边和顶点加入生成树的顶点集合和边集合。由于无向连通网的生成树总是存在的,根据生成树性质,对于N个结点的连通图,需要N-1条边使得任意两个结点之间相互连通,因此算法结束的条件是从边集中选择N-1条边。如果所有的边遍历完,选择边的数量小于N-1,则该连通网的输入数据存在错误导致图不连通。
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
4 算法实现及主要函数模块说明
为了实现Prim算法和Kruskal算法,程序中定义了边结点用来表示一条边的两个顶点及权值数据,边结点edgeNode定义如下:
typedef struct edgeNode
{
int from,to;
int cost;
}
EDGENODE;
4.1 Prim算法及主要的功能函数模块说明
(1)creatMatrix函数模块
函数原型:void creatMatrix(int **AdjMatrix,int n,int e);
函数功能:以文件读入或者键盘输入的方式构造邻接矩阵,AdjMatrix表示邻接矩阵,n和e分别表示图的顶点数和边数。
(2)printMatrix函数模块
函数原型:void printMatrix(int **AdjMatrix,int n);
函数功能:输出邻接矩阵,AdjMatrix表示邻接矩阵,n表示图的顶点数。
(3)initEdgeSet函数模块
函数原型:void initEdgeSet(int **AdjMatrix,EDGENODE *edgeSet,int n,int start);
函数功能:将start与其他顶点之间的权值存放到候选边集合edgeSet中。
(4)chooseEdge函数模块
函数原型:int chooseEdge(EDGENODE *edgeSet,int n,int index);
函数功能:从候选边集edgeSet中选出最小边结点,其中 index为edgeSet选取边时下标的起始位置。
(5)modfiyEdgeSet函数模块
函数原型:void modfiyEdgeSet(int **AdjMatrix,EDGENODE *edgeSet,int n,int index,int to);
函数功能:新加入结点后,调整候选边集edgeSet中的待选边结点,其中to为新加入到中的顶点编号。
(6)primMst最小生成树函数模块
函数原型:void primMst(int **AdjMatrix,EDGENODE *edgeSet,int n,int start);
函数功能:通过顶点从候选边集中选取最小边构造最小生成树。
(7)printMst最小生成树输出函数模块
函数原型:void printMst(EDGENODE *edgeSet,int n);
函数功能:输出最终最小生成树中的选取的边和最小权值和。

这篇关于无向连通网的最小生成树算法[第1部分]的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/992976

相关文章

MySQL中动态生成SQL语句去掉所有字段的空格的操作方法

《MySQL中动态生成SQL语句去掉所有字段的空格的操作方法》在数据库管理过程中,我们常常会遇到需要对表中字段进行清洗和整理的情况,本文将详细介绍如何在MySQL中动态生成SQL语句来去掉所有字段的空... 目录在mysql中动态生成SQL语句去掉所有字段的空格准备工作原理分析动态生成SQL语句在MySQL

springboot+dubbo实现时间轮算法

《springboot+dubbo实现时间轮算法》时间轮是一种高效利用线程资源进行批量化调度的算法,本文主要介绍了springboot+dubbo实现时间轮算法,文中通过示例代码介绍的非常详细,对大家... 目录前言一、参数说明二、具体实现1、HashedwheelTimer2、createWheel3、n

Java利用docx4j+Freemarker生成word文档

《Java利用docx4j+Freemarker生成word文档》这篇文章主要为大家详细介绍了Java如何利用docx4j+Freemarker生成word文档,文中的示例代码讲解详细,感兴趣的小伙伴... 目录技术方案maven依赖创建模板文件实现代码技术方案Java 1.8 + docx4j + Fr

Java编译生成多个.class文件的原理和作用

《Java编译生成多个.class文件的原理和作用》作为一名经验丰富的开发者,在Java项目中执行编译后,可能会发现一个.java源文件有时会产生多个.class文件,从技术实现层面详细剖析这一现象... 目录一、内部类机制与.class文件生成成员内部类(常规内部类)局部内部类(方法内部类)匿名内部类二、

使用Jackson进行JSON生成与解析的新手指南

《使用Jackson进行JSON生成与解析的新手指南》这篇文章主要为大家详细介绍了如何使用Jackson进行JSON生成与解析处理,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 核心依赖2. 基础用法2.1 对象转 jsON(序列化)2.2 JSON 转对象(反序列化)3.

java中使用POI生成Excel并导出过程

《java中使用POI生成Excel并导出过程》:本文主要介绍java中使用POI生成Excel并导出过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录需求说明及实现方式需求完成通用代码版本1版本2结果展示type参数为atype参数为b总结注:本文章中代码均为

在java中如何将inputStream对象转换为File对象(不生成本地文件)

《在java中如何将inputStream对象转换为File对象(不生成本地文件)》:本文主要介绍在java中如何将inputStream对象转换为File对象(不生成本地文件),具有很好的参考价... 目录需求说明问题解决总结需求说明在后端中通过POI生成Excel文件流,将输出流(outputStre

SpringBoot实现MD5加盐算法的示例代码

《SpringBoot实现MD5加盐算法的示例代码》加盐算法是一种用于增强密码安全性的技术,本文主要介绍了SpringBoot实现MD5加盐算法的示例代码,文中通过示例代码介绍的非常详细,对大家的学习... 目录一、什么是加盐算法二、如何实现加盐算法2.1 加盐算法代码实现2.2 注册页面中进行密码加盐2.

Mysql删除几亿条数据表中的部分数据的方法实现

《Mysql删除几亿条数据表中的部分数据的方法实现》在MySQL中删除一个大表中的数据时,需要特别注意操作的性能和对系统的影响,本文主要介绍了Mysql删除几亿条数据表中的部分数据的方法实现,具有一定... 目录1、需求2、方案1. 使用 DELETE 语句分批删除2. 使用 INPLACE ALTER T

Java时间轮调度算法的代码实现

《Java时间轮调度算法的代码实现》时间轮是一种高效的定时调度算法,主要用于管理延时任务或周期性任务,它通过一个环形数组(时间轮)和指针来实现,将大量定时任务分摊到固定的时间槽中,极大地降低了时间复杂... 目录1、简述2、时间轮的原理3. 时间轮的实现步骤3.1 定义时间槽3.2 定义时间轮3.3 使用时