最短路径算法

原理

1. 算出目前数据中,起点到终点的最短路径

2. 路径从短到长获取目前最短的路径,设置标识,有标识的不参与下一步循环

 

package com.jason.base.arithmetic;

import lombok.extern.slf4j.Slf4j;

/**
 * 自己版本的最短路径
 *
 * @author:heyaolei
 * @create: 2023-03-07
 */
@Slf4j
public class JasonShortPath {

    //所有可能的路径
    double[][] allPathArr;
    //全局路径长度
    double[] globalPathLength;
    //全局路径途经节点
    String[] globalNodeArr;
    //标识是否为最短节点
    static boolean[] flag;
    //开始节点
    static int beginNode;
    //节点数量
    static int nodeNum;

    /**
     * 路径数据初始化
     */
    public void init() {
        //初始化
        allPathArr = new double[nodeNum][nodeNum];
        globalNodeArr = new String[nodeNum];
        globalPathLength = new double[nodeNum];
        flag = new boolean[nodeNum];

        //测试方便
        allPathArr = new double[][]{{0, 3, 2, -1, -1, -1},
                {3, 0, 6, 4.5, 3.5, -1},
                {2, 6, 0, 5, -1, -1, -1},
                {-1, 4.5, 5, 0, 3, -1},
                {-1, 3.5, -1, 3, 0, 1},
                {-1, -1, -1, 1, 0}};
        flag = new boolean[]{false, false, false, false, false, false};
        globalPathLength = new double[]{Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE};

        //获取线路图数据
//        Scanner scanner = new Scanner(System.in);
//        for (int i = 0; i < nodeNum; i++) {
//            flag[i] = false;
//            for (int j = i + 1; j < nodeNum; j++) {
//                log.info("input node: " + i + " - " + j);
//                double value = Double.valueOf(scanner.next());
//                allPathArr[i][j] = value;
//                allPathArr[j][i] = allPathArr[i][j];
//            }
//            allPathArr[i][i] = 0;
//        }
    }

    /**
     * 计算开始节点到各个节点距离
     */
    public void calculate() {
        int localBeginNode = beginNode;
        double minPathLength = 0;
        String localNodePath = String.valueOf(beginNode);

        for (int i = 0; i < nodeNum; i++) {
            //获取从开始节点到各个节点的路线
            for (int j = 0; j < nodeNum; j++) {
                //flag=true表示已经是最有路径,路径>0表示这个路径是合法的
                if (!flag[j] && allPathArr[localBeginNode][j] >= 0) {
                    //新路径(新节点+最短路径)< 当前路径
                    if (allPathArr[localBeginNode][j] + minPathLength < globalPathLength[j]) {
                        globalPathLength[j] = allPathArr[localBeginNode][j] + minPathLength;
                        globalNodeArr[j] = localNodePath + " -> " + j;
                    }
                }
            }

            minPathLength = Double.MAX_VALUE;
            //确认路线是最短路线
            for (int j = 0; j < nodeNum; j++) {
                if (!flag[j] && globalPathLength[j] < minPathLength) {
                    minPathLength = globalPathLength[j];
                    localBeginNode = j;
                }
            }
            //设置最短节点
            flag[localBeginNode] = true;
            if (minPathLength > 0) {
                localNodePath = globalNodeArr[localBeginNode];
            }
        }
    }

    /**
     * main
     *
     * @param args
     */
    public static void main(String[] args) {
        beginNode = 2;
        nodeNum = 6;
        JasonShortPath shortPath = new JasonShortPath();
        shortPath.init();
        shortPath.calculate();
        shortPath.printResult();
    }


    /**
     * 打印记录
     */
    public void printResult() {
        for (int i = 0; i < nodeNum; i++) {
            log.info("节点链路: " + globalNodeArr[i] + "   长度:" + globalPathLength[i]);
        }

    }
}

 

posted on 2023-03-11 13:04  周公  阅读(55)  评论(0编辑  收藏  举报

导航