【算法基础实验】图论-最小生成树Kruskal实现

预备知识

【算法基础实验】图论-UnionFind连通性检测之quick-union_union find 判断是否成环-CSDN博客

【算法基础实验】排序-最小优先队列MinPQ_最小优先队列实现-CSDN博客

理论知识

Kruskal算法是一种用于查找加权无向图的最小生成树的贪心算法。最小生成树是一个连通的子图,它包含所有顶点,并使得所有边的权重之和最小。Kruskal算法的核心思想是:

  1. 边排序:首先将图中的所有边按权重从小到大排序。
  2. 边选择:从权重最小的边开始,依次选择边加入到生成树中,但要确保不会形成环。
  3. 循环停止:直到树中包含 V-1 条边(其中 V 是图中的顶点数)时,算法停止。

Kruskal算法的主要步骤涉及使用并查集(Union-Find)来检测是否形成环。并查集有效地管理和合并不同的连通分量,并检查两个顶点是否已经在同一个连通分量中。

Kruskal 算法的时间复杂度

Kruskal算法的时间复杂度主要取决于边的排序和并查集操作:

  • 排序:O(E log E),其中 E 是边的数量。
  • Union-Find 操作:每次操作的时间复杂度接近 O(1),总体复杂度为 O(E log V)。

Prim 算法是一条边一条边地来构造最小生成树,每一步都为一棵树添加一条边。Kruskal 算法构造最小生成树的时候也是一条边一条边地构造,但不同的是它寻找的边会连接一片森林中的两棵树。我们从一片由 棵单顶点的树构成的森林开始并不断将两棵树合并(用可以找到的最短边)直到只剩下一棵树,它就是最小生成树。

实验数据

8
16
4 5 0.35
4 7 0.37
5 7 0.28
0 7 0.16
1 5 0.32
0 4 0.38
2 3 0.17
1 7 0.19
0 2 0.26
1 2 0.36
1 3 0.29
2 7 0.34
6 2 0.40
3 6 0.52
6 0 0.58
6 4 0.93

算法流程

在这里插入图片描述

代码实现

import edu.princeton.cs.algs4.In;
import edu.princeton.cs.algs4.StdOut;public class myKruskalMST {private myLinkedQueue<myEdge> mst;private double totalWeight;public myKruskalMST(myEdgeWeightedGraph G){mst = new myLinkedQueue<myEdge>();myMinPQ<myEdge> pq = new myMinPQ<myEdge>();for(myEdge e:G.edges()) pq.insert(e);myQuickUnion uf = new myQuickUnion(G.V());while(!pq.isEmpty() && mst.size()<G.V()-1){myEdge e = pq.delMin();int v=e.either(),w=e.other(v);if(uf.connected(v,w)) continue;uf.union(v,w);mst.enqueue(e);}}public Iterable<myEdge> edges(){ return mst; }public double weight(){totalWeight = 0.0;for(myEdge e:edges())totalWeight += e.weight();return totalWeight;}public static void main(String[] args){In in = new In(args[0]);myEdgeWeightedGraph G = new myEdgeWeightedGraph(in);myKruskalMST mst = new myKruskalMST(G);for(myEdge e:mst.edges())StdOut.println(e);StdOut.printf("%.5f\n", mst.weight());}
}

代码详解

这段代码实现了 Kruskal 算法来求解最小生成树。以下是对代码各部分的详细解释:

类变量和构造函数

java复制代码
private myLinkedQueue<myEdge> mst; // 用于存储最小生成树的边
private double totalWeight; // 最小生成树的总权重public myKruskalMST(myEdgeWeightedGraph G) {mst = new myLinkedQueue<myEdge>();myMinPQ<myEdge> pq = new myMinPQ<myEdge>();for (myEdge e : G.edges()) pq.insert(e);myQuickUnion uf = new myQuickUnion(G.V());while (!pq.isEmpty() && mst.size() < G.V() - 1) {myEdge e = pq.delMin();int v = e.either(), w = e.other(v);if (uf.connected(v, w)) continue;uf.union(v, w);mst.enqueue(e);}
}
  • mst:使用 myLinkedQueue 存储 Kruskal 算法中选择的边,即最小生成树的边。
  • totalWeight:记录最小生成树的总权重。
  • 构造函数
    • 初始化 mst 队列,用于保存最终的最小生成树的边。
    • 使用 myMinPQ(最小优先队列)来存储和排序图中的边。
    • 将图 G 中的所有边插入优先队列 pq 中。
    • 使用 myQuickUnion 实现并查集,以检测并合并连通分量。
    • 通过一个 while 循环,不断从 pq 中取出权重最小的边,并检查是否形成环。如果不会形成环,则将边加入 mst 队列。

辅助方法:edges() 和 weight()

java复制代码
public Iterable<myEdge> edges() {return mst;
}public double weight() {totalWeight = 0.0;for (myEdge e : edges())totalWeight += e.weight();return totalWeight;
}
  • edges():返回最小生成树中的所有边。
  • weight():计算并返回最小生成树的总权重。

main方法

java复制代码
public static void main(String[] args) {In in = new In(args[0]);myEdgeWeightedGraph G = new myEdgeWeightedGraph(in);myKruskalMST mst = new myKruskalMST(G);for (myEdge e : mst.edges())StdOut.println(e);StdOut.printf("%.5f\n", mst.weight());
}
  • main():从输入文件读取加权无向图数据,构造 myEdgeWeightedGraph 对象 G
    • 调用 myKruskalMST 类生成最小生成树。
    • 打印最小生成树的边和总权重。

总结

Kruskal 算法通过从权重最小的边开始逐步构建最小生成树。使用并查集来管理连通分量,有效避免形成环。在这段代码中,Kruskal 算法以 myKruskalMST 类实现,使用优先队列 myMinPQ 来处理边的排序,并使用 myQuickUnion 来实现并查集操作。最终,代码输出了最小生成树中的边及其总权重。

实验步骤

C:\Users\xyz\IdeaProjects\algrithoms\src>javac myKruskalMST.java             C:\Users\xyz\IdeaProjects\algrithoms\src>java myKruskalMST data\tinyEWG.txt  
0-7 0.16
2-3 0.17
1-7 0.19
0-2 0.26
5-7 0.28
4-5 0.35
6-2 0.40
1.81000

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/407043.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

uniapp使用live-pusher进行人脸识别打卡(安卓跟ios)

效果图 代码 使用live-pusher <live-pusher idlivePusher class"livePusher" mode"FHD" beauty"0" whiteness"0" aspect"9:16"min-bitrate"1000" audio-quality"16KHz" device-position"fron…

Apple pencil有替代品吗?2024开学季推荐五款实惠又好用的电容笔

如果只是用于学习和办工的话&#xff0c;Apple pencil是有替代品的&#xff0c;虽然Apple Pencil的性能不错&#xff0c;但它的高昂价格让很多用户不得不开始寻求性价比更高的平替电容笔。那么&#xff0c;在众多选择中&#xff0c;如何挑选一款合适的电容笔呢&#xff1f;以下…

【iOS】Block底层分析

目录 前言Block底层结构Block捕获变量原理捕获局部变量&#xff08;auto、static&#xff09;全局变量捕获实例self Block类型Block的copyBlock作为返回值将Block赋值给__strong指针Block作为Cocoa API中方法名含有usingBlock的方法参数Block作为GCD API的方法参数Block属性的写…

光性能 -- 边模抑制比眼图

最小边模抑制比 在最坏的发射条件下&#xff0c;主模的平均光功率与最显著边模的光功率之比即最小边模抑制比。 什么是边模 理想情况下&#xff0c;光模块发射的信号应当只是有特定波长的光信号。但实际情况下不仅有一个特定波长的主信号&#xff0c;还有一些其他波长的存在&…

Java学习笔记(02)接口的使用

1、接口关键字&#xff1a;interface 2、接口内部结构的说明&#xff1a; 可以声明抽象方法&#xff0c;属性由public static final修饰&#xff0c;但都会默认。 不可以声明&#xff1a;构造器&#xff0c;代码块等。 3、格式&#xff1a;class A extends SuperA implements…

开放式耳机别人能听到吗?现在开放式耳机用防漏音效果越来越好!

回答&#xff1a; 开放式耳机的通透的设计允许一部分声音泄露出来&#xff0c;因此站在您旁边的人确实有可能听到您耳机中的声音&#xff0c;尤其是当音量设置得比较高时。开放式耳机通常提供更为自然和宽敞的听感&#xff0c;但牺牲了一定的隔音效果和隐私性。如果您需要在公…

探索提示工程 Prompt Engineering的奥妙

一、探索提示工程 1. 介绍通用人工智能和专用人工智能 人工智能&#xff08;AI&#xff09;可以分为通用人工智能&#xff08;AGI&#xff09;和专用人工智能&#xff08;Narrow AI&#xff09;。AGI是一种能够理解、学习和执行任何人类可以完成的任务的智能。与此相对&#x…

《深入浅出多模态》(八)多模态经典模型:MiniGPT4

&#x1f389;AI学习星球推荐&#xff1a; GoAI的学习社区 知识星球是一个致力于提供《机器学习 | 深度学习 | CV | NLP | 大模型 | 多模态 | AIGC 》各个最新AI方向综述、论文等成体系的学习资料&#xff0c;配有全面而有深度的专栏内容&#xff0c;包括不限于 前沿论文解读、…

【Qt】输入类控件QComboBox

目录 输入类控件QComboBox 例子&#xff1a;使用下拉框模拟点餐 例子&#xff1a;从文件中加载下拉框的选项 输入类控件QComboBox QComboBox表示下拉框 核心属性 属性说明 currentText 当前选中的⽂本 currentIndex 当前选中的条⽬下标. 从 0 开始计算. 如果当前没有条…

Deepin【2】:Deepin系统盘扩容

Deepin【2】&#xff1a;Deepin系统盘扩容 1、进入live系统1.1、live系统入步骤 2、连接网络3、新增系统仓库4、安装gparted应用5、使用gparted进行扩容操作5.1、观察当前分区5.2、压缩data分区5.3、Rootb分区合并空闲空间5.4、Rootb分区压缩空间5.5、Roota合并空闲空间5.6、核…

高速服务区公共厕所为什么要升级做智慧公厕?@卓振思众

高速服务区智慧公厕的建设&#xff0c;将为公共卫生设施带来了全新的变革&#xff0c;可实现以下功能和效益&#xff1a; 一、服务区智慧公厕功能精准厕位引导&#xff1a;高速服务区人流量大&#xff0c;尤其是在节假日等高峰时期&#xff0c;厕所常常人满为患。智慧公厕系统可…

【论文阅读】A Closer Look at Parameter-Efficient Tuning in Diffusion Models

Abstract 大规模扩散模型功能强大&#xff0c;但微调定制这些模型&#xff0c;内存和时间效率都很低。 本文通过向大规模扩散模型中插入小的学习器(称为adapters)&#xff0c;实现有效的参数微调。 特别地&#xff0c;将适配器的设计空间分解为输入位置、输出位置、函数形式的…

基于Ubuntu22.04 安装SSH服务

安全外壳协议&#xff08;Secure Shell&#xff0c;简称 SSH&#xff09;是一种在不安全网络上用于安全远程登录和其他安全网络服务的协议。 SSH 由 IETF 的网络小组&#xff08;Network Working Group&#xff09;所制定&#xff0c;SSH 为建立在应用层基础上的安全协议。SSH…

Excel“取消工作表保护”忘记密码并恢复原始密码

文章目录 1.前言2.破解步骤3. 最终效果4.参考文献 1.前言 有时候别人发来的Excel中有些表格不能编辑&#xff0c;提示如下&#xff0c;但是又不知道原始密码 2.破解步骤 1、打开您需要破解保护密码的Excel文件&#xff1b; 2、依次点击菜单栏上的视图—宏----录制宏&#xf…

音频格式转换方法有哪些?学会这3个方法让音频转换从未如此简单

在音乐的世界里&#xff0c;我们常常遇到各种格式的音频文件&#xff0c;它们就像是五线谱上的音符&#xff0c;需要不同的乐器来演绎。 热爱音乐的我&#xff0c;经常需要将这些音频文件转换成适合我设备播放的格式。在线音频格式转换工具&#xff0c;就像是我的音乐小助手&a…

【传输层协议】UDP协议 {端口号的范围划分;UDP数据报格式;UDP协议的特点;UDP的缓冲区;基于UDP的应用层协议}

一、再谈端口号 1.1 端口号标识网络进程 如何通过端口号找到主机上的网络进程&#xff1f; 在socket编程中bind绑定是最为重要的一步&#xff1a;他将套接字与指定的本地 IP 地址和端口号关联起来&#xff0c;这意味着指定的套接字可以接收来自指定 IP 地址和端口号的数据包…

收银系统源码助力零售门店数字化升级

一、国内零售业数字化转型迈入深水区 近年来&#xff0c;我国零售业数字化进程显著加速&#xff0c;从线上电商到新零售模式&#xff0c;再到利用大数据、人工智能等技术优化供应链、提升体验&#xff0c;每一步都见证了行业的深刻变革。随着零售行业进入存量市场竞争&#xf…

微服务设计原则——高性能:存储设计

文章目录 1.读写分离2.分库分表3.动静分离4.冷热分离5.重写轻读6.数据异构参考文献 任何一个系统&#xff0c;从单机到分布式&#xff0c;从前端到后台&#xff0c;功能和逻辑各不相同&#xff0c;但干的只有两件事&#xff1a;读和写。而每个系统的业务特性可能都不一样&#…

LangChain框架深度解析:对Chains组件的全方位探索与实战案例

文章目录 前言一、Chains二、LLMChain⭐1.LLMChain介绍2.LLMChain案例 三、SimpleSequentialChain⭐1.SimpleSequentialChain介绍2.SimpleSequentialChain案例 四、SequentialChain⭐1.SequentialChain介绍2.SequentialChain案例 五、RouterChain⭐1.RouterChain介绍2.RouterCh…

leetcode:2520. 统计能整除数字的位数(python3解法)

难度&#xff1a;简单 给你一个整数 num &#xff0c;返回 num 中能整除 num 的数位的数目。 如果满足 nums % val 0 &#xff0c;则认为整数 val 可以整除 nums 。 示例 1&#xff1a; 输入&#xff1a;num 7 输出&#xff1a;1 解释&#xff1a;7 被自己整除&#xff0c;因…