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!...
    }
}

效果图

 

 

有用就支持一下

猜你喜欢

转载自www.cnblogs.com/sunupo/p/10047627.html