重點技術-20181003-支援數學圖論物件和演算法的圖形庫JGraph
JGraphT支援數學圖論物件和演算法的免費Java圖形庫。JGraphT支援的圖形包括:
- 有向圖和無向圖
- 加權圖、非加權圖、帶標籤的圖以及任何使用者自定義邊
- 支援各種多樣性邊屬性:簡單圖、多重圖和偽圖(pseudograph)
- 對圖只讀訪問:允許模組設定內部圖形的“只讀”訪問
- 圖可監聽:支援通過外部監聽器跟蹤修改事件
- 子圖可根據其他圖中的子檢視變化自動更新
- 支援上述所有功能組合使用
-----------------Maven引入-----------------
<dependency> <groupId>org.jgrapht</groupId> <artifactId>jgrapht-core</artifactId> <version>1.1.0</version> </dependency>
-----------------程式碼使用-----------------
import java.util.List; import java.util.Set;
import org.jgrapht.Graph; import org.jgrapht.alg.ConnectivityInspector; import org.jgrapht.alg.KosarajuStrongConnectivityInspector; import org.jgrapht.alg.interfaces.ShortestPathAlgorithm; import org.jgrapht.alg.interfaces.StrongConnectivityAlgorithm; import org.jgrapht.alg.shortestpath.DijkstraShortestPath; import org.jgrapht.graph.DefaultDirectedGraph; import org.jgrapht.graph.DefaultEdge; import org.jgrapht.graph.DirectedAcyclicGraph; import org.jgrapht.traverse.BreadthFirstIterator; import org.jgrapht.traverse.ClosestFirstIterator; import org.jgrapht.traverse.DegeneracyOrderingIterator; import org.jgrapht.traverse.DepthFirstIterator; import org.jgrapht.traverse.RandomWalkIterator; import org.jgrapht.traverse.TopologicalOrderIterator;
// 用向無環圖 public class TestDirectedAcyclicGraph { private static Graph<String, DefaultEdge> graph = null;
public static void testStrongConn(Graph graph) { StrongConnectivityAlgorithm<String, DefaultEdge> scAlg = new KosarajuStrongConnectivityInspector<String, DefaultEdge>(graph);
List<Set<String>> stronglyConnetedSet = scAlg.stronglyConnectedSets();
System.out.println("強相聯結點:"); for (int i = 0; i < stronglyConnetedSet.size(); i++) { System.out.println(stronglyConnetedSet.get(i)); } System.out.println(); }
public static void testWeakConn(Graph graph) { ConnectivityInspector<String, DefaultEdge> connectivityInspector = new ConnectivityInspector<String, DefaultEdge>(graph); List<Set<String>> weaklyConnectedSet = connectivityInspector.connectedSets(); System.out.println("弱相聯結點:"); for (int i = 0; i < weaklyConnectedSet.size(); i++) { System.out.println(weaklyConnectedSet.get(i)); } System.out.println(); }
public static void main(String[] args) { graph = createGraphWithoutCircle();//無環圖 System.out.println("拓撲搜尋------");// 注意,此方法僅適用於有向無環圖(DAG) TopologicalOrderIterator<String, DefaultEdge> tfi = new TopologicalOrderIterator<String, DefaultEdge>(graph); while (tfi.hasNext()) { System.out.print(tfi.next() + " "); } System.out.println(""); // graph = createGraphWithCircle();//有環圖
testStrongConn(graph); testWeakConn(graph);
System.out.println("圖的所有節點------"); System.out.println(graph); if (graph instanceof DirectedAcyclicGraph) { System.out.println("b的祖先------"); System.out.println(((DirectedAcyclicGraph<String, DefaultEdge>) graph).getAncestors("b"));// 祖先
System.out.println("b的後代------"); System.out.println(((DirectedAcyclicGraph<String, DefaultEdge>) graph).getDescendants("b"));// 後代 }
System.out.println("廣度優先搜尋------"); BreadthFirstIterator<String, DefaultEdge> bfi = new BreadthFirstIterator<String, DefaultEdge>(graph, "a"); while (bfi.hasNext()) { System.out.print(bfi.next() + " "); }
System.out.println(""); System.out.println("深度優先搜尋------"); DepthFirstIterator<String, DefaultEdge> dfi = new DepthFirstIterator<String, DefaultEdge>(graph, "a"); while (dfi.hasNext()) { System.out.print(dfi.next() + " "); }
System.out.println(""); System.out.println("退化搜尋------"); DegeneracyOrderingIterator<String, DefaultEdge> dofi = new DegeneracyOrderingIterator<String, DefaultEdge>(graph); while (dofi.hasNext()) { System.out.print(dofi.next() + " "); }
System.out.println(""); System.out.println("隨機搜尋------"); RandomWalkIterator<String, DefaultEdge> ccfi = new RandomWalkIterator<String, DefaultEdge>(graph); while (ccfi.hasNext()) { System.out.print(ccfi.next() + " "); }
System.out.println(""); System.out.println("最近優先搜尋------"); ClosestFirstIterator<String, DefaultEdge> cfi = new ClosestFirstIterator<String, DefaultEdge>(graph); while (cfi.hasNext()) { System.out.print(cfi.next() + " "); }
// 列印從a到i的路徑(邊沒有權重) System.out.println("從a到i的最短路徑:"); DijkstraShortestPath<String, DefaultEdge> dijkstraAlg = new DijkstraShortestPath<>(graph); ShortestPathAlgorithm.SingleSourcePaths<String, DefaultEdge> iPaths = dijkstraAlg.getPaths("a"); System.out.println(iPaths.getPath("i") + "\n");
// 列印從b到d的路徑(邊沒有權重) System.out.println("從b到d:"); ShortestPathAlgorithm.SingleSourcePaths<String, DefaultEdge> cPaths = dijkstraAlg.getPaths("b"); System.out.println(cPaths.getPath("d")); }
// 無環有向圖 private static Graph<String, DefaultEdge> createGraphWithoutCircle() { // 無環圖 DirectedAcyclicGraph<String, DefaultEdge> directedAcyclicGraph = new DirectedAcyclicGraph<String, DefaultEdge>(DefaultEdge.class); String v1 = "a"; String v2 = "b"; String v3 = "c"; String v4 = "d"; String v5 = "e";
// add the vertices directedAcyclicGraph.addVertex(v1); directedAcyclicGraph.addVertex(v2); directedAcyclicGraph.addVertex(v3); directedAcyclicGraph.addVertex(v4); directedAcyclicGraph.addVertex(v5);
// add edges to create a circuit directedAcyclicGraph.addEdge(v1, v5); directedAcyclicGraph.addEdge(v5, v3); directedAcyclicGraph.addEdge(v3, v4); directedAcyclicGraph.addEdge(v1, v2); directedAcyclicGraph.addEdge(v4, v2);
return directedAcyclicGraph; }
// 帶環有向圖 private static Graph<String, DefaultEdge> createGraphWithCircle() { // 普通有向圖(當前例子帶環) DefaultDirectedGraph<String, DefaultEdge> directedGraph = new DefaultDirectedGraph<String, DefaultEdge>(DefaultEdge.class); directedGraph.addVertex("a"); directedGraph.addVertex("b"); directedGraph.addVertex("c"); directedGraph.addVertex("d"); directedGraph.addVertex("e"); directedGraph.addVertex("f"); directedGraph.addVertex("h"); directedGraph.addVertex("i"); directedGraph.addEdge("a", "b"); directedGraph.addEdge("b", "c"); directedGraph.addEdge("c", "d"); directedGraph.addEdge("d", "a"); directedGraph.addEdge("c", "e"); directedGraph.addEdge("f", "h"); directedGraph.addEdge("f", "i");
return directedGraph; } }