zoukankan      html  css  js  c++  java
  • 算法7-11:强连通分量

    首先介绍的是一个强大的连接。顶点之间的紧密联系是假设v达到w,然后,w你可以达到v。顶点之间的强连接就表示顶点之间能够双向到达,也就是说两个顶点在一个回路上。


    介绍了强连接。那什么是强连接部件呢?强连接部件就是可以相互到达的全部顶点的集合。一个图中可能会有多个强连接。


    强连接在离散数学中属于等价关系,也就是说它具有反射性,相反性。传递性。


    应用


    强连接在生物学中有所应用。食物链就是一个样例。下图展示了一个非常小的食物链。



    在食物链中,强连接部件表示在同一个部件中的生物共享同样的能量流。


    强连接部件在软件project中也有应用。一个软件中有很多模块。假设将软件中的模块看成顶点,将模块之间的依赖关系看成图论中的边。那么这就是一个有向图。在同一个强连接部件中的模块之间耦合度是比較高的。依照软件设计原则,耦合度高的模块往往要放在一个包中。

    所以,强连接部件能够检測模块之间的耦合度。能够软件结构的优化起到指导作用。


    算法


    为了计算出一个有向图中有多少强连接部件,世界上有一种名叫Kosaraj Sharir算法,这样的算法很easy。可是比較神奇,一般的人无法直观地看出为什么这样算可以得到正确的结果。


    这个算法的分为两个阶段。

    第一个阶段就是对有向图的反图进行拓扑排序。注意是反图。第二个阶段就像连接部件算法一样,依照排序结果,对未曾訪问过的节点运行DFS。


    有了这种思路。那么代码就立即出来了:


    public class StrongComponent {
        private boolean[] visited;
        private int[] id;
        private int count;
     
        public StrongComponent(Digraph G) {
            visited = new boolean[G.V()];
            id = new int[G.V()];
     
            // 计算反图的拓扑排序
            Digraph R = G.reverse();
            Iterable<Integer> sort = new DepthFirstOrder(R).sort();
     
            // 对每一个未曾訪问过的顶点运行dfs
            for (int v : sort) {
                if (!visited[v]) {
                    dfs(G, v);
                    count++;
                }
            }
        }
     
        public int count() {
            return count;
        }
     
        public boolean stronglyConnected(int v, int w) {
            return id[v] == id[w];
        }
     
        public int id(int v) {
            return id[v];
        }
     
        private void dfs(Digraph G, int v) {
            visited[v] = true;
            id[v] = count;
            for (int w : G.adj(v)) {
                if (!visited[w]) {
                    dfs(G, w);
                }
            }
        }
    }


    版权声明:本文博主原创文章。博客,未经同意不得转载。

  • 相关阅读:
    ES6实现小案例--自定义弹框
    ES6 字符串、数值与布尔值、函数参数的解构赋值
    ES6 对象的解构赋值
    ES6 数组的解构赋值
    CentOS7安装mysql后无法启动服务,提示Unit not found
    CentOS7安装MySQL报错,解决Failed to start mysqld.service: Unit not found
    redis修改密码
    redis入门
    如何在本地远程连接linux虚拟机上面的mysql
    Linux下彻底卸载mysql详解
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/4907353.html
Copyright © 2011-2022 走看看