把有向图相邻顶点之间添加方向相反的两条边相当于无向图
先上代码,后面有空再添加注释
根据文末图4.2对应的例题,可以验证程序结果
1 package com.sun.GraphTheoryReport; 2 import org.jgrapht.*; 3 import org.jgrapht.alg.connectivity.*; 4 import org.jgrapht.alg.interfaces.ShortestPathAlgorithm.*; 5 import org.jgrapht.alg.interfaces.*; 6 import org.jgrapht.alg.shortestpath.*; 7 import org.jgrapht.graph.*; 8 9 import java.util.*; 10 public class CalShortestPath { 11 // private String[] str={"u0","u1","u2","u3","u4","u5","u6","u7"}; 12 // private int[] startPoint={0,0,0,1,1,3,3,3,3,2,4,5,5,4,6}; 13 // private int[] endPoint={1,3,2,4,3,4,5,6,2,6,5,6,7,7,7}; 14 // private double[] weights={2,8,1,1,6,5,1,2,7,9,3,4,6,9,3}; 15 private String[] str ; 16 private int[] startPoint ; 17 private int[] endPoint ; 18 private double[] weights ; 19 private Double[][] Dij; 20 /** 21 * @param str 顶点集合 22 * 用三个一维数据保存图Graph的信息 23 * @param startPoint 边的起点 24 * @param endPoint 边的终点 25 * @param weights 对应边的权值 26 * @param Dij 任意两点之间的最短距离 27 */ 28 public CalShortestPath(String[] str, int[] startPoint, int[] endPoint,double[] weights) { 29 super(); 30 this.str = str; 31 this.startPoint = startPoint; 32 this.endPoint = endPoint; 33 this.weights=weights; 34 this.Dij=new Double[str.length][str.length]; 35 } 36 37 /** 38 * 主方法 39 * @param args 40 */ 41 public static void main(String[] args) { 42 String[] str={"u0","u1","u2","u3","u4","u5","u6","u7"}; 43 int[] startPoint={0,0,0,1,1,3,3,3,3,2,4,5,5,4,6}; 44 int[] endPoint={1,3,2,4,3,4,5,6,2,6,5,6,7,7,7}; 45 double[] weights={2,8,1,1,6,5,1,2,7,9,3,4,6,9,3}; 46 CalShortestPath calShortestPath = new CalShortestPath(str, startPoint, endPoint, weights); 47 calShortestPath.getShortestPath(); 48 Double[][] dij2 = calShortestPath.getDij(); 49 for (int i = 0; i < dij2.length; i++) { 50 System.out.print("["); 51 for (int j = 0; j < dij2.length; j++) { 52 System.out.print(Integer.parseInt(dij2[i][j].toString().substring(0, dij2[i][j].toString().indexOf(".")))+","); 53 } 54 System.out.println("]\n"); 55 } 56 } 57 /** 58 * 得到一个有向带权图,本来是做无向图的还没写好,这个每队相邻顶点之间用两条方向相反的边表示 59 * @return 返回一个带权有向图 60 */ 61 public SimpleDirectedWeightedGraphgenSimpleDirectedWeightedGraph(){ 62 SimpleDirectedWeightedGraph directedGraph = 63 new SimpleDirectedWeightedGraph (DefaultWeightedEdge.class); 64 for (int i = 0; i < str.length; i++) { 65 directedGraph.addVertex(str[i]); 66 } 67 DefaultWeightedEdge[] addEdgeUp=new DefaultWeightedEdge[startPoint.length]; 68 DefaultWeightedEdge[] addEdgeDown=new DefaultWeightedEdge[startPoint.length]; 69 for (int i = 0; i < endPoint.length; i++) { 70 addEdgeUp[i] = directedGraph.addEdge(str[startPoint[i]], str[endPoint[i]]); 71 addEdgeDown[i] = directedGraph.addEdge(str[endPoint[i]], str[startPoint[i]]); 72 directedGraph.setEdgeWeight(addEdgeUp[i], weights[i]); 73 directedGraph.setEdgeWeight(addEdgeDown[i], weights[i]); 74 } 75 return directedGraph; 76 } 77 /** 78 * 根据得到的带权有向图,Dijkstra计算最短路径,并保存他们的路径权值之和到数组Dij中 79 */ 80 public void getShortestPath(){ 81 SimpleDirectedWeightedGraph directedGraph =genSimpleDirectedWeightedGraph(); 82 83 // System.out.println("Shortest path from u0 to u7:"); 84 DijkstraShortestPath dijkstraAlg = 85 new DijkstraShortestPath<>(directedGraph); 86 // SingleSourcePaths iPaths = dijkstraAlg.getPaths("u0"); 87 // System.out.println(iPaths.getPath("u7") + "\n"); 88 89 for (int i = 0; i < str.length; i++) { 90 for (int j = 0; j < str.length; j++) { 91 GraphPathpath = dijkstraAlg.getPath(str[i], str[j]); 92 // System.out.println(path + ":" + path.getWeight()); 93 Dij[i][j]=path.getWeight(); 94 } 95 } 96 // FloydWarshallShortestPaths floydWarshallShortestPaths = new FloydWarshallShortestPaths<>(directedGraph); 97 // System.out.println(floydWarshallShortestPaths.getPath("u0","u7")); 98 } 99 100 public Double[][] getDij() { 101 return Dij; 102 } 103 104 }
最短路径矩阵
[0,2,1,7,3,6,9,12,]
[2,0,3,5,1,4,7,10,]
[1,3,0,7,4,7,9,12,]
[7,5,7,0,4,1,2,5,]
[3,1,4,4,0,3,6,9,]
[6,4,7,1,3,0,3,6,]
[9,7,9,2,6,3,0,3,]
[12,10,12,5,9,6,3,0,]
用Java画图
package com.sun.GraphTheoryReport; import com.mxgraph.layout.*; import com.mxgraph.swing.*; import org.jgrapht.*; import org.jgrapht.ext.*; import org.jgrapht.graph.*; import javax.swing.*; import java.awt.*; /** * A demo applet that shows how to use JGraphX to visualize JGraphT graphs. Applet based on * JGraphAdapterDemo. * */ public class CustomJGraphXAdapter extends JApplet { private static final long serialVersionUID = 2202072534703043194L; private static final Dimension DEFAULT_SIZE = new Dimension(530*2, 320*2); private JGraphXAdapterjgxAdapter; /** * An alternative starting point for this demo, to also allow running this applet as an * application. * * @param args command line arguments */ public static void main(String[] args) { CustomJGraphXAdapter applet = new CustomJGraphXAdapter(); applet.init(); JFrame frame = new JFrame(); frame.getContentPane().add(applet); frame.setTitle("JGraphT Adapter to JGraphX Demo"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); frame.setVisible(true); } @Override public void init() { // create a JGraphT graph ListenableGraph directedGraph = new DefaultListenableGraph<>(new DefaultDirectedGraph<>(DefaultWeightedEdge.class)); // create a visualization using JGraph, via an adapter jgxAdapter = new JGraphXAdapter<>(directedGraph); setPreferredSize(DEFAULT_SIZE); mxGraphComponent component = new mxGraphComponent(jgxAdapter); component.setConnectable(false); component.getGraph().setAllowDanglingEdges(false); getContentPane().add(component); resize(DEFAULT_SIZE); String[] str={"u0","u1","u2","u3","u4","u5","u6","u7"}; int[] startPoint={0,0,0,1,1,3,3,3,3,2,4,5,5,4,6}; int[] endPoint={1,3,2,4,3,4,5,6,2,6,5,6,7,7,7}; double[] weights={2,8,1,1,6,5,1,2,7,9,3,4,6,9,3}; for (int i = 0; i < str.length; i++) { directedGraph.addVertex(str[i]); } DefaultWeightedEdge[] addEdgeUp=new DefaultWeightedEdge[startPoint.length]; DefaultWeightedEdge[] addEdgeDown=new DefaultWeightedEdge[startPoint.length]; for (int i = 0; i < endPoint.length; i++) { addEdgeUp[i] = directedGraph.addEdge(str[startPoint[i]], str[endPoint[i]]); addEdgeDown[i] = directedGraph.addEdge(str[endPoint[i]], str[startPoint[i]]); } // positioning via jgraphx layouts mxCircleLayout layout = new mxCircleLayout(jgxAdapter); // center the circle int radius = 300; layout.setX0((DEFAULT_SIZE.width )/2 -250); layout.setY0((DEFAULT_SIZE.height )/2 -310); layout.setRadius(radius); layout.setMoveCircle(true); layout.execute(jgxAdapter.getDefaultParent()); // that's all there is to it!... } }
效果图