Kosaraju算法(发现强连通分图算法)
生活随笔
收集整理的這篇文章主要介紹了
Kosaraju算法(发现强连通分图算法)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
??????? 看論文的時候,看到Kosaraju算法。Kosaraju是一個強連通分圖的發現算法,如有代碼中有詳細的注釋,所以就不贅述了。直接上碼(使用webgraph庫實現,在我之前的文章中,對webgraph有相關的介紹):
package cn.edu.dlut.wisdom; import it.unimi.dsi.fastutil.ints.*; import it.unimi.dsi.fastutil.objects.*; import it.unimi.dsi.webgraph.*; import java.util.Comparator; /** * @author You Wang * Kosaraju算法,用來發現強連通分量 * 算法過程如下: * G:有向圖;S:空棧 * while S中不包含G中所有頂點 * 任選一個不在S中的節點v * 從v開始進行深度優先搜素,每次將訪問到的節點u壓入S中 * 反轉G中所有的邊 * while S非空 * 從S中彈出結點v * 從v開始進行深度優先搜索,所有訪問到的結點構成強連通分圖,記錄下來 * 從G和S中刪除這些結點 */ public class Kosaraju { private ImmutableGraph graph; private ImmutableGraph igraph; private ImmutableGraph workGraph; private ObjectAVLTreeSet<IntAVLTreeSet> sccs; private IntArrayList stack; private boolean[] visited; private int numNodes; public Kosaraju(ImmutableGraph graph) { this.graph = graph; igraph = Transform.transpose(graph); numNodes = graph.numNodes(); } public Kosaraju(ImmutableGraph graph, ImmutableGraph igraph) { this.graph = graph; this.igraph = igraph; numNodes = graph.numNodes(); } public ObjectAVLTreeSet<IntAVLTreeSet> compute() { stack = new IntArrayList(); visited = new boolean[numNodes]; workGraph = graph; // dfs the graph, adding nodes to the stack for(int i = 0; i < numNodes; i++) if(!stack.contains(i)) dfs(i, true); workGraph = igraph; Comparator cmp = new Comparator() { public int compare(Object o1, Object o2) { if(o1 instanceof IntAVLTreeSet && o2 instanceof IntAVLTreeSet) { IntAVLTreeSet s1 = (IntAVLTreeSet)o1; IntAVLTreeSet s2 = (IntAVLTreeSet)o2; if (s1.size() != s2.size()) return s1.size() - s2.size(); else { int[] a1 = s1.toIntArray(); int[] a2 = s2.toIntArray(); for (int i = 0; i < a1.length; i++) if (a1[i] != a2[i]) return a1[i] - a2[i]; return 0; } } else throw new IllegalArgumentException("The argument must be an IntAVLTreeSet"); } }; sccs = new ObjectAVLTreeSet<IntAVLTreeSet>(cmp); while(!stack.isEmpty()) { IntAVLTreeSet component = new IntAVLTreeSet(); int v = stack.popInt(); component.add(v); dfs(v, false); // any components we visited are strongly connected // remove them from the starck and add them to the component IntIterator it = stack.iterator(); while(it.hasNext()) { int n = it.nextInt(); if(!visited[n]) { component.add(n); it.remove(); } } if(component.size() != 0) sccs.add(component); } return sccs; } private void dfs(int node, boolean forward) { visited[node] = forward; if(workGraph.outdegree(node) == 0) { if(forward) stack.push(node); return; } for(int n : workGraph.successorArray(node)) if(visited[n] != forward) dfs(n, forward); if(forward) stack.push(node); } }?
??????? 其中的set排序,個人感覺不盡完美,不知道各位有何高見,歡迎指正。
總結
以上是生活随笔為你收集整理的Kosaraju算法(发现强连通分图算法)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 实用教程 活动目录介绍及安装指南
- 下一篇: .net框架读书笔记---基础类型