1. 程式人生 > >Java使用Jgrapht,求無向(有向)加權圖的最短路徑

Java使用Jgrapht,求無向(有向)加權圖的最短路徑

把有向圖相鄰頂點之間新增方向相反的兩條邊相當於無向圖

先上程式碼,後面有空再添加註釋

根據文末圖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 SimpleDirectedWeightedGraph<String, DefaultWeightedEdge> genSimpleDirectedWeightedGraph(){ 62 SimpleDirectedWeightedGraph<String, DefaultWeightedEdge> directedGraph = 63 new SimpleDirectedWeightedGraph<String, DefaultWeightedEdge>(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<String, DefaultWeightedEdge> directedGraph =genSimpleDirectedWeightedGraph(); 82 83 // System.out.println("Shortest path from u0 to u7:"); 84 DijkstraShortestPath<String, DefaultWeightedEdge> dijkstraAlg = 85 new DijkstraShortestPath<>(directedGraph); 86 // SingleSourcePaths<String, DefaultWeightedEdge> 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 GraphPath<String, DefaultWeightedEdge> path = dijkstraAlg.getPath(str[i], str[j]); 92 // System.out.println(path + ":" + path.getWeight()); 93 Dij[i][j]=path.getWeight(); 94 } 95 } 96 // FloydWarshallShortestPaths<String, DefaultWeightedEdge> 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 JGraphXAdapter<String, DefaultWeightedEdge> jgxAdapter;

    /**
     * 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<String, DefaultWeightedEdge> 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!...
    }
}

效果圖

 

 

 
 

 

有用就支援一下