1. 程式人生 > 其它 >最短路徑圖計算

最短路徑圖計算

技術標籤:演算法資料結構動態規劃

import java.util.LinkedList;

/**
 * 點資料結構
 */
public class Point {
    private Double value;//距離值
    private LinkedList<String> route;//最短路徑

    public Point() {
    }

    public Point(Double value, String startPoint,String endPoint) {
        LinkedList<String> route = new LinkedList<>();
        route.addFirst(startPoint);
        route.addLast(endPoint);
        this.value = value;
        this.route = route;
    }

    public Point(Double value, LinkedList<String> routeFirst, LinkedList<String> routeLast) {
        LinkedList<String> strings = new LinkedList<>();
        strings.addAll(routeFirst);
        boolean status = false;//是否已經過濾出第一個重複節點
        for (String name : routeLast) {
            if (status) {
                strings.addLast(name);
            } else {
                status = true;
            }
        }

        this.value = value;
        this.route = strings;
    }


    public Double getValue() {
        return value;
    }

    public LinkedList<String> getRoute() {
        return route;
    }


    /**
     * 顯示路線與最短距離
     * @return
     */
    @Override
    public String toString() {
        StringBuilder sbf = new StringBuilder("[");
        int index = 0;
        for (String name : route) {
            sbf.append(name);
            index++;
            if (index < route.size()) {
                sbf.append("->");
            } else {
                sbf.append("]");
            }
        }
        sbf.append("=").append(value);
        return sbf.toString();
    }
}


import java.util.*;

/**
 * 矩陣計算資料結構
 */
public class Matrix {
    private Set<String> areaSet;//地理位置列表
    private List<Point> points;//所有路線
    private Map<String, Map<String, Point>> minPoints;//最短路線圖

    public Matrix() {
        areaSet = new HashSet<>();
        points = new ArrayList<>();
    }

    /**
     * 新增點資訊
     *
     * @param startPoint
     * @param endPoint
     * @param distance
     */
    public void addRoute(String startPoint, String endPoint, Double distance) {
        areaSet.add(startPoint);
        areaSet.add(endPoint);
        Point point = new Point(distance, startPoint, endPoint);//建立點資料
        points.add(point);
    }

    /**
     * 初始化矩陣,並計算最短路徑
     */
    public Map<String, Map<String, Point>> exec() {
        int max = this.areaSet.size();//矩陣的維度
        String[] areaArray = new String[max];
        this.areaSet.toArray(areaArray);
        Map<String, Integer> index = new HashMap<>();
        Map<Integer, String> indexSort = new HashMap<>();
        for (int i = 0, j = areaArray.length; i < j; i++) {
            index.put(areaArray[i], i);
            indexSort.put(i, areaArray[i]);
        }

        this.minPoints = new HashMap<>(max);

        //構造二維陣列
        Point[][] points = new Point[max][max];
        for (Point point : this.points) {
            String x = point.getRoute().getFirst();
            String y = point.getRoute().getLast();
            points[index.get(x)][index.get(y)] = point;
        }

        for (int pointer = 0; pointer < max; pointer++) {
            for (int x = 0; x < max; x++) {
                if (x == pointer) continue;
                for (int y = 0; y < max; y++) {
                    if (x == y || y == pointer) continue;
                    if (points[x][pointer] == null) continue;
                    if (points[pointer][y] == null) continue;
                    if (points[x][y] == null) {//
                        Point onePoint = points[x][pointer];
                        Point twoPoint = points[pointer][y];
                        double value = onePoint.getValue() + twoPoint.getValue();
                        Point point = new Point(value, onePoint.getRoute(), twoPoint.getRoute());
                        points[x][y] = point;//構造路線
                    } else if (points[x][pointer].getValue() + points[pointer][y].getValue() < points[x][y].getValue()) {//更新
                        Point onePoint = points[x][pointer];
                        Point twoPoint = points[pointer][y];
                        double value = onePoint.getValue() + twoPoint.getValue();
                        Point point = new Point(value, onePoint.getRoute(), twoPoint.getRoute());
                        points[x][y] = point;//覆蓋路線
                    } else {
                        //丟棄
                    }
                }
            }
        }
        //記錄結果
        for (int x = 0; x < max; x++) {
            Map<String, Point> pointMap = new HashMap<>();
            for (int y = 0; y < max; y++) {
                if (x == y) {
                    Point point = new Point(0D, indexSort.get(y), indexSort.get(y));
                    pointMap.put(indexSort.get(y), point);
                } else {
                    pointMap.put(indexSort.get(y), points[x][y]);
                }
            }
            this.minPoints.put(indexSort.get(x), pointMap);
        }
        return this.minPoints;
    }


    /**
     * 測試入口
     *
     * @param args
     */
    public static void main(String[] args) {
        Matrix matrix = new Matrix();
        matrix.addRoute("a", "b", 2D);
        matrix.addRoute("a", "c", 1D);
        matrix.addRoute("b", "e", 3D);
        matrix.addRoute("c", "d", 3D);
        matrix.addRoute("c", "f", 4D);
        matrix.addRoute("d", "e", 6D);
        matrix.addRoute("d", "e", 6D);
        matrix.addRoute("f", "e", 2D);
        matrix.addRoute("c", "f", 4D);
        matrix.addRoute("e", "g", 5D);
        matrix.addRoute("f", "g", 16D);
        matrix.addRoute("g", "h", 4D);
        matrix.addRoute("g", "i", 7D);
        matrix.addRoute("h", "i", 5D);
        Map<String, Map<String, Point>> exec = matrix.exec();//得出最近路線與距離值
        System.out.println("所有路線圖為: "+exec);
        System.out.println("指定路線圖為: "+exec.get("a").get("i"));//a到i的最小距離路線圖

    }

}

執行結果