【算法基础实验】图论-基于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.mfbz.cn/a/577500.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何消除浏览器SmartScreen对网站“不安全”提示?

面对互联网时代用户对网站安全性和可信度的严苛要求&#xff0c;网站运营者时常遭遇Microsoft Defender SmartScreen&#xff08;SmartScreen&#xff09;提示网站不安全的困扰。本文将剖析SmartScreen判定网站不安全的原因&#xff0c;并为运营者提供应对策略&#xff0c;以恢…

codeforce#933 题解

E. Rudolf and k Bridges 题意不讲了&#xff0c;不如去题干看图。 传统dp&#xff0c;每个点有两个选择&#xff0c;那么建桥要么不建。需要注意的是在状态转移的时候&#xff0c;桥是有长度的&#xff0c;如果不建需要前d格中建桥花费最少的位置作为状态转移的初态。 #incl…

发那科FANUC机器人R-2000iB平衡缸维修攻略

在发那科机器人中&#xff0c;平衡缸扮演着稳定机械臂运动的关键角色。它通过内部的压力调节来平衡负载&#xff0c;保证机器人的精准定位和平稳操作。一旦出现法兰克机械手平衡缸故障或损坏&#xff0c;机器人的性能可能会大打折扣&#xff0c;因此及时且正确的FANUC机械手平衡…

uniapp获取当前位置及检测授权状态

uniapp获取当前位置及检测授权定位权限 文章目录 uniapp获取当前位置及检测授权定位权限效果图创建js文件permission.jslocation.js 使用 效果图 Android设备 点击 “设置”&#xff0c;跳转应用信息&#xff0c;打开“权限即可”&#xff1b; 创建js文件 permission.js 新建…

HTTP基础知识

1. HTTP常见的状态码有哪些&#xff1f; 常见状态码&#xff1a; 200&#xff1a;服务器已成功处理了请求。 通常&#xff0c;这表示服务器提供了请求的网页。 301 &#xff1a; (永久移动) 请求的网页已永久移动到新位置。 服务器返回此响应(对 GET 或 HEAD 请求的响应)时&a…

Java使用SpringBoot和EasyExcel 实现动态数据导出实战

Java使用SpringBoot和EasyExcel 实现动态数据导出实战 1、前言2、【资源地址】3、代码示例(demo)4、目前Java实现数据导出为Excel方式5、依赖6、总结 1、前言 工作中有用到将数据导出为Excel的场景&#xff0c;在此记录下。在日常开发中&#xff0c;Excel文件处理是一项常见的…

LeetCode 面试题 08.02——迷路的机器人

阅读目录 1. 题目2. 解题思路3. 代码实现 1. 题目 2. 解题思路 此题就是一个典型的图搜索题&#xff0c;一种就是广度优先搜索&#xff0c;一种就是深度优先搜索。 3. 代码实现 class Solution { public:vector<vector<int>> pathWithObstacles(vector<vecto…

软件需求管理规程(Word原件2024)

软件开发人员及用户往往容易忽略信息沟通&#xff0c;这导致软件开发出来后不能很好地满足用户的需要&#xff0c;从而造成返工。而返工不仅在技术上给开发人员带来巨大的麻烦&#xff0c;造成人力、物力的浪费&#xff0c;而且软件的性能也深受影响。所以在软件项目开发周期的…

Bellman Ford算法:解决负权边图的最短路径问题

Bellman Ford算法的介绍 在计算机科学的世界中&#xff0c;Bellman Ford算法是一种解决单源最短路径问题的算法&#xff0c;它可以处理有负权边的图。这个算法的名字来源于两位科学家Richard Bellman和Lester Randolph Ford&#xff0c;他们是这个算法的发明者。 这个算法的主…

hive启动beeline报错

问题一在zpark启动集群报错 出现上面的问题执行以下代码 chmod 777 /opt/apps/hadoop-3.2.1/logs 问题二启动beeline报错 执行 cd /opt/apps/hadoop-3.2.1 bin/hadoop dfsadmin -safemode leave 问题三执行查询语句报错 执行 set hive.exec.mode.local.autotrue;

公考相丽君政治素养研习课

公考相丽君政治素养研习课&#xff0c;是广大公考学子提升政治素养、深化政治理解的宝贵课程。相丽君老师以其深厚的政治理论功底和丰富的教学经验&#xff0c;为学员们呈现了一堂生动而深刻的政治课。课程中&#xff0c;相老师深入浅出地讲解了政治理论的基本概念和核心思想&a…

Windows系统下将MySQL数据库表内的数据全量导入Elasticsearch

目录 下载安装Logstash 配置Logstash配置文件 运行配置文件 查看导入结果 使用Logstash将sql数据导入Elasticsearch 下载安装Logstash 官网地址 选择Windows系统&#xff0c;需下载与安装的Elasticsearch相同版本的&#xff0c;下载完成后解压安装包。 配置Logstash配…

ChuanhuChatGPT集成百川大模型

搭建步骤&#xff1a; 拷贝本地模型&#xff0c;把下载好的Baichuan2-7B-Chat拷贝到models目录下 修改modules\models\base_model.py文件&#xff0c;class ModelType增加Baichuan Baichuan 16 elif "baichuan" in model_name_lower: model_type ModelType.Ba…

(超全)python图像处理详细解析(3)

图像处理 23.保存视频每一帧图像24.把png图像转换成jpg并保存25.改变图像尺寸26.改变图像比例27.旋转图像28.亮度调整29.log对数调整30.判断图像对比度31.调整强度&#xff08;1&#xff09;强度调节&#xff08;2&#xff09;uint8转float 32.绘制直方图和均衡化33.彩色图片三…

基于streamlit快速部署机器学习项目(Public URL)

基于streamlit的AIGC项目前端展示 1.Streamlit 简介与入门1.1 安装 Streamlit1.2 开发Streamlit应用程序1.3 启动并运行1.3.1 本地运行1.3.2 部署 现在LLM技术发展迅速&#xff0c;很多人在学习的时候&#xff0c;都想展示效果&#xff0c;并且想部署在服务器上&#xff0c;但是…

原型链prototype、__proto、constructor的那些问题整理

再了解原型链之前,我们先来看看构造函数和实例对象的打印结构 - 函数 这里我们定义一个构造函数Fn,然后打印它的结构吧 function Fn(){} console.dir(Fn)控制台得到结构 从上面结构我们能看的出来,函数有两种原型,一种是作为函数特有的原型:prototype,另一种是作为对象的__…

数字旅游:通过科技赋能,创新旅游服务模式,提供智能化、个性化的旅游服务,满足游客多元化、个性化的旅游需求

目录 一、数字旅游的概念与内涵 二、科技赋能数字旅游的创新实践 1、大数据技术的应用 2、人工智能技术的应用 3、物联网技术的应用 4、云计算技术的应用 三、智能化、个性化旅游服务的实现路径 1、提升旅游服务的智能化水平 2、实现旅游服务的个性化定制 四、数字旅…

计算机网络大框架图形

如标题&#xff0c;精心画了一个计算机网络的框架性的图&#xff0c;包含了计算机网络的核心思想&#xff0c;在此分享和备份下。各层具体协议参考TCP/IP常用协议栈图解-CSDN博客

工厂数字化三部曲/业务、数据和IT融合

工厂数字化三部曲: 业务、数据和IT融合 在当今数字化转型的潮流中&#xff0c;企业面临着将业务、数据和IT融合的挑战和机遇。数字化转型不仅是技术上的升级&#xff0c;更是对企业运营模式和管理体系的全面优化和重构。通过业务“数字化”阶段的细致分析和整合&#xff0c;以及…

葡萄牙语翻译中文难吗,葡译中如何翻译比较好?

葡萄牙&#xff0c;一个充满魅力的国度&#xff0c;拥有着悠久的历史和丰富的文化传统。葡萄牙语作为这个国家的官方语言&#xff0c;在全球范围内享有广泛的声誉。那么&#xff0c;葡萄牙语翻译中文难吗&#xff1f;又该如何进行高质量的翻译呢&#xff1f; 业内人士指出&…
最新文章