【算法基础实验】图论-基于DFS的连通性检测

基于DFS的连通性检测

理论基础

在图论中,连通分量是无向图的一个重要概念,特别是在处理图的结构和解析图的组成时。连通分组件表示图中的一个子图,在这个子图中任意两个顶点都是连通的,即存在一条路径可以从一个顶点到达另一个顶点,并且这个子图是最大的,即不能通过添加更多的顶点来增加连通性。对于有向图,这通常被称为强连通分量。

基于DFS的连通分量算法

书中4.1.6节提到的基于深度优先搜索(DFS)的连通分量算法用于识别和处理无向图中的连通分量。这个算法的基本思想是使用DFS遍历图中的每个顶点,同时记录哪些顶点是连通的。

算法步骤

  1. 初始化:为每个顶点准备一个标记数组 marked[] 来记录每个顶点是否被访问过,另外用一个数组 id[] 来记录每个顶点所属的连通分量的标识符。还需要一个计数器 count 来统计连通分量的数量。
  2. DFS遍历:从任意未被访问的顶点开始,执行DFS遍历。在遍历过程中,标记所有可达的顶点为已访问,同时将这些顶点的 id[] 设置为当前的连通分量标识符。
  3. 连通分量标识:每次在DFS遍历开始前增加连通分量计数器 count,并将遍历过程中访问的所有顶点的连通分量标识设置为这个计数器的值。
  4. 重复执行:重复上述过程,直到图中的所有顶点都被访问过。

应用

  • 图的结构分析:识别图中的独立部分或者紧密相关的群组。
  • 网络设计:确定网络中的独立组件,以优化设计和提高稳定性。
  • 社交网络:识别社交网络中的社区或者群组。

通过这种基于DFS的连通分量算法,可以有效地解析和处理图的结构,对于复杂网络的分析尤其有用。

数据结构

private boolean[] marked
private int[] id
private int count
myBag
myGraph

实验数据和算法流程

这里使用tinyG.txt来构成实验用的无向图

注意算法流程中count,marked[],id[]的变化

请添加图片描述

代码实现

import edu.princeton.cs.algs4.In;
import edu.princeton.cs.algs4.StdOut;public class myCC {private boolean[] marked;private int[] id;private int count;public myCC(myGraph G){marked = new boolean[G.V()];id = new int[G.V()];for(int s=0;s<G.V();s++){if(!marked[s]){dfs(G,s);//这里是精髓所在,每次dfs回到这里就说明互相连通的一组顶点已经完成遍历,//也就确定了一个连通分量count++;                }}}private void dfs(myGraph G, int v){marked[v] = true;id[v] = count;for(int w:G.adj(v)){if(!marked[w]){dfs(G,w);}}}public boolean connected(int v, int w){return id[v]==id[w];}public int id(int v){return id[v];}public int count(){return count;}public static void main(String[] args){myGraph G = new myGraph(new In(args[0]));myCC cc = new myCC(G);int M = cc.count();StdOut.println(M + " components");myBag<Integer>[] components = (myBag<Integer>[]) new myBag[M];for(int i=0;i<M;i++){components[i] = new myBag<Integer>();}for(int v=0;v<G.V();v++){components[cc.id(v)].add(v);}for(int i=0;i<M;i++){for(int v:components[i]) StdOut.print(v+" ");StdOut.println();}}
}

代码详解

这段代码实现了一个基于深度优先搜索(DFS)的连通分量(CC)类 myCC,用于确定无向图中所有的连通分量。下面是详细的代码解释:

类定义和变量


public class myCC {private boolean[] marked;  // 标记数组,用于标记每个顶点是否已经被访问过private int[] id;          // 每个顶点所属的连通分量标识private int count;         // 连通分量的数量
  • marked 数组用于记录图中的每个顶点是否已经被访问。
  • id 数组用于存储每个顶点所属的连通分量的ID。
  • count 用于计数图中连通分量的总数。

构造函数


public myCC(myGraph G){marked = new boolean[G.V()];id = new int[G.V()];for(int s = 0; s < G.V(); s++) {if (!marked[s]) {dfs(G, s);count++;  // 完成一个连通分量的搜索后,增加连通分量的计数}}
}

构造函数遍历图中的所有顶点,对于每个未标记的顶点,执行DFS来标记和记录所有能从该顶点访问到的顶点,这些顶点构成一个连通分量。每次DFS调用结束后,连通分量数 count 加一。

DFS 方法


private void dfs(myGraph G, int v){marked[v] = true;id[v] = count;for (int w : G.adj(v)) {if (!marked[w]) {dfs(G, w);}}
}

dfs 方法标记顶点 v 为已访问,并将其连通分量ID设置为当前的 count。然后递归地访问所有与顶点 v 直接相连的未标记顶点。

连通分量的辅助方法


public boolean connected(int v, int w) { return id[v] == id[w]; }
public int id(int v) { return id[v]; }
public int count() { return count; }

这些方法提供了:

  • connected(v, w) 检查两个顶点是否属于同一个连通分量。
  • id(v) 返回顶点 v 的连通分量ID。
  • count() 返回图中连通分量的总数。

主方法


public static void main(String[] args){myGraph G = new myGraph(new In(args[0]));myCC cc = new myCC(G);int M = cc.count();StdOut.println(M + " components");myBag<Integer>[] components = (myBag<Integer>[]) new myBag[M];for (int i = 0; i < M; i++) {components[i] = new myBag<Integer>();}for (int v = 0; v < G.V(); v++) {components[cc.id(v)].add(v);}for (int i = 0; i < M; i++) {for (int v : components[i]) StdOut.print(v + " ");StdOut.println();}
}

主方法使用 myCC 类来处理一个从文件读取的图,并输出所有的连通分量。这里,连通分量被存储在一个 myBag 数组中,每个 myBag 对象存储一个连通分量的所有顶点,然后输出每个连通分量的顶点。

这段代码是一个完整的图连通分量识别实现,使用DFS作为基本的遍历策略。

实验

代码编译

javac myCC.java

运行代码

将实验数据tinyG.txt导入代码后,myCC可以检测到3个连通分量,并逐行将连通分量中的元素打印出来

java myCC ..\data\tinyG.txt               
3 components
6 5 4 3 2 1 0
8 7
12 11 10 9

参考资料

算法(第4版)人民邮电出版社

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

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

相关文章

Flutter应用下拉菜单设计DropdownButtonFormField控件介绍

文章目录 DropdownButtonFormField介绍使用方法重点代码说明属性解释 注意事项 DropdownButtonFormField介绍 Flutter 中的 DropdownButtonFormField 是一个用于在表单中选择下拉菜单的控件。它是 DropdownButton 和 TextFormField 的组合&#xff0c;允许用户从一组选项中选择…

井字棋游戏

1. 游戏创建 1.1导包 from tkinter import * import numpy as np import math import tkinter.messagebox 1.2 窗口内容 1.2.1创建一个窗口 root Tk() # 窗口名称 root.title("井字棋 from Sun") 1.2.2 创建一个框架&#xff0c;将其放置在窗口中 Frame1 F…

汽车底盘域的学习笔记

前言&#xff1a;底盘域分为传统车型底盘域和新能源车型底盘域&#xff08;新能源系统又可以分为纯电和混动车型&#xff0c;有时间可以再研究一下&#xff09; 1&#xff1a;传统车型底盘域 细分的话可以分为四个子系统 传动系统 行驶系统 转向系统 制动系统 1.1传动系…

什么样的内外网文档摆渡,可以实现安全高效传输?

内外网文档摆渡通常指的是在内网&#xff08;公司或组织的内部网络&#xff09;和外网&#xff08;如互联网&#xff09;之间安全地传输文件的过程。这个过程需要特别注意安全性&#xff0c;因为内网往往包含敏感数据&#xff0c;直接连接内网和外网可能会带来安全风险。因此会…

设计模式——终止模式之两阶段终止模式

文章目录 1. 错误思路2. 两阶段终止模式2.1 利用 isInterrupted2.2 利用停止标记interrupt-打断park Two Phase Termination 在一个线程 T1 中如何“优雅”终止线程 T2&#xff1f;这里的【优雅】指的是给 T2 一个料理后事的机会。 1. 错误思路 使用线程对象的 stop() 方法停…

GEM TSU Interface Details and IEEE 1588 Support

摘要&#xff1a;Xilinx ZNYQ ULTRASCALE MPSOC的GEM和1588的使用 对于FPGA来说&#xff0c;只需要勾选一些znyq的配置就行了&#xff0c;其余的都是软件的工作&#xff1b; 所有配置都勾选之后&#xff0c;最终会露出来的接口如下&#xff1a; GEM需要勾选的配置如下&#xf…

15.Blender Eevee和Cycles渲染引擎对比

初步介绍 Eevee是实时渲染的引擎&#xff0c;会省略一些解算方式&#xff0c;尤其对光线和阴影 Cycles会考虑这些因素&#xff0c;所以会对光线和阴影的表达更加真实&#xff0c;有一个实时光线追踪的功能 Cycles渲染完之后&#xff0c;每移动一次画面&#xff0c;都会重新渲染…

政安晨:【Keras机器学习示例演绎】(十九)—— 可视化网络学习内容

目录 简介 设置 建立特征提取模型 设置梯度上升过程 设置端到端滤波器可视化回路 可视化目标层中的前 64 个滤波器 政安晨的个人主页&#xff1a;政安晨 欢迎 &#x1f44d;点赞✍评论⭐收藏 收录专栏: TensorFlow与Keras机器学习实战 希望政安晨的博客能够对您有所裨益&…

基于Rust的多线程 Web 服务器

构建多线程 Web 服务器 在 socket 上监听 TCP 连接解析少量的 HTTP 请求创建一个合适的 HTTP 响应使用线程池改进服务器的吞吐量优雅的停机和清理注意&#xff1a;并不是最佳实践 创建项目 ~/rust ➜ cargo new helloCreated binary (application) hello package~/rust ➜ma…

kaggle之皮肤癌数据的深度学习测试

kaggle之皮肤癌数据的深度学习测试 近期一直在肝深度学习 很久之前&#xff0c;曾经上手搞过一段时间的深度学习&#xff0c;似乎是做轮胎花纹的识别&#xff0c;当初用的是TensorFlow&#xff0c;CPU版本的&#xff0c;但已经很长时间都没弄过了 现在因为各种原因&#xff…

全面解析平台工程与 DevOps 的区别与联系

平台工程的概念非常流行&#xff0c;但很多开发人员仍然不清楚它是如何实际运作的&#xff0c;这是非常正常的。 平台工程是与 DevOps 并行吗&#xff1f;还是可以相互替代&#xff1f;或者 DevOps 和平台工程是两个完全不同的概念&#xff1f; 一种比较容易将两者区分开来的方…

打包的意义 作用等前端概念集合 webpack基础配置等

基础网页是什么&#xff1f; 在学校最基础的三剑客 原生JS CSS H5就可以开发静态网页了 对于浏览器而言也能识别这些基础的文件和语法&#xff0c;真正的所见即所得&#xff0c;非常直接。 为什么要使用框架库&#xff1f; 对于常用的前端框架而言&#xff0c;无论是Vue Rea…

普通屏幕已过时?裸眼3D屏幕显示效果更胜一筹!

随着多媒体技术的迅猛进步&#xff0c;我们日常生活中的内容展现方式&#xff0c;已经经历了前所未有的变革。在这其中&#xff0c;裸眼3D屏幕的应用&#xff0c;无疑是最为引人注目的亮点&#xff0c;它相较于传统屏幕&#xff0c;在显示效果上展现出了鲜明的优势&#xff0c;…

RGB灯珠的控制-单片机通用模板

RGB灯珠的控制-单片机通用模板 一、RGB控制的原理二、RGB.c的实现三、RGB.h的实现四、color色彩空间变换以及控制渐变一、RGB控制的原理 ①通过IO发送脉冲识别0/1编码,组合24Bit的RGB数据,从而控制RGB;②每个RGB灯珠通过DIN、DOU进行级联起来;③通过HSV色彩转换成RGB从而控…

ArcGIS批量寻找图层要素中的空洞

空洞指的是图层中被要素包围所形成的没有被要素覆盖的地方&#xff0c;当图层要素数量非常庞大时&#xff0c;寻找这些空洞就不能一个一个的通过目测去寻找了&#xff0c;需要通过使用工具来实现这一目标。 一、【要素转线】工具 利用【要素转线】工具可以将空洞同图层要素处于…

【触摸案例-多点触摸的案例 Objective-C语言】

一、我们来做这个多点触摸的案例 1.首先呢,按着这个option键啊,可以模拟多点触摸, 然后呢,再去怎么着去画圈儿, 它这个里边就会产生一个imageView,跟着你去变,会有这么一个效果, 那么,首先啊,我们新建一个项目, Name:03-多点触摸的案例 1)首先,我们把控制器的v…

Xcode for Mac:强大易用的集成开发环境

Xcode for Mac是一款专为苹果开发者打造的集成开发环境&#xff08;IDE&#xff09;&#xff0c;它集成了代码编辑器、编译器、调试器等一系列开发工具&#xff0c;让开发者能够在同一界面内完成应用的开发、测试和调试工作。 Xcode for Mac v15.2正式版下载 Xcode支持多种编程…

ShardingSphere 5.x 系列【25】 数据分片原理之 SQL 解析

有道无术,术尚可求,有术无道,止于术。 本系列Spring Boot 版本 3.1.0 本系列ShardingSphere 版本 5.4.0 源码地址:https://gitee.com/pearl-organization/study-sharding-sphere-demo 文章目录 1. 分片执行流程1.1 Simple Push Down1.2 SQL Federation2. SQL 解析2.1 解析…

分布式WEB应用中会话管理的变迁之路

Session一词直译为“会话”&#xff0c;意指有始有终的一系列动作&#xff0f;消息。Session是Web应用蓬勃发展的产物之一&#xff0c;在Web应用中隐含有“面向连接”和“状态保持”两个含义&#xff0c;同时也指代了Web服务器与客户端之间进行状态保持的解决方案。 在Web应用…

基于JAVA实现的推箱子小游戏

Java推箱子小游戏实现&#xff1a; 推箱子小游戏曾经在我们的童年给我们带来了很多乐趣。推箱子这款游戏现在基本上没人玩了&#xff0c;甚至在新一代人的印象中都已毫无记忆了。。。但是&#xff0c;这款游戏可以在一定程度上锻炼自己的编程能力。 窗口画面设计&#xff1a;i…