日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Kosaraju算法(发现强连通分图算法)

發布時間:2023/12/20 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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算法(发现强连通分图算法)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。