Dijkstra(迪杰斯特拉)算法是典型的最短路径路由算法

Dijkstra(迪杰斯特拉)算法是典型的最短路径路由算法:

Dijkstra(迪杰斯特拉)算法是典型的最短路径路由算法,用于计算一个节点到其他所有节点的最短路径。每一条路径都会打印出来

主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。

终点:用于存储未遍历的点集合为空

        private Set<Node> open=new HashSet<Node>();//open用于存储未遍历的点
private Set<Node> close=new HashSet<Node>();//close用来存储已遍历的节点
      

Dijkstra算法是很有代表性的最短路径算法,在很多专业课程中都作为基本内容有详细的介绍,比如数据结构、图论、运筹学等。

Dijkstra对象用于计算起始节点到所有其他节点的最短路径


程序中最短路径使用的图:




        package com.neusoft.data.structure;


import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * Dijkstra(迪杰斯特拉)算法是典型的最短路径路由算法,用于计算一个节点到其他所有节点的最短路径。每一条路径都会打印出来
 * 主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。
 * 终点:用于存储未遍历的点集合为空
 * private Set<Node> open=new HashSet<Node>();//open用于存储未遍历的点
 * private Set<Node> close=new HashSet<Node>();//close用来存储已遍历的节点
 * Dijkstra算法是很有代表性的最短路径算法,在很多专业课程中都作为基本内容有详细的介绍,比如数据结构、图论、运筹学等。
 * Dijkstra对象用于计算起始节点到所有其他节点的最短路径
 */
public class DijkstraPath {
    /*
     * Node对象用于封装节点信息,包括名字和子节点
     */
    public class Node {
        private String name;
        //Node:孩子节点  Integer:权重
        private Map<Node, Integer> child = new HashMap<Node, Integer>();

        public Node(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }

        public Map<Node, Integer> getChild() {
            return child;
        }

    }

    /*
     * MapBuilder用于初始化数据源,返回图的起始节点
     */
    public class MapBuilder {
        public Node build(Set<Node> open, Set<Node> close) {
            Node nodeA = new Node("A");
            Node nodeB = new Node("B");
            Node nodeC = new Node("C");
            Node nodeD = new Node("D");
            Node nodeE = new Node("E");
            Node nodeF = new Node("F");
            Node nodeG = new Node("G");
            Node nodeH = new Node("H");
            nodeA.getChild().put(nodeB, 1);
            nodeA.getChild().put(nodeC, 1);
            nodeA.getChild().put(nodeD, 4);
            nodeA.getChild().put(nodeG, 5);
            nodeA.getChild().put(nodeF, 2);
            nodeB.getChild().put(nodeA, 1);
            nodeB.getChild().put(nodeF, 2);
            nodeB.getChild().put(nodeH, 4);
            nodeC.getChild().put(nodeA, 1);
            nodeC.getChild().put(nodeG, 3);
            nodeD.getChild().put(nodeA, 4);
            nodeD.getChild().put(nodeE, 1);
            nodeE.getChild().put(nodeD, 1);
            nodeE.getChild().put(nodeF, 1);
            nodeF.getChild().put(nodeE, 1);
            nodeF.getChild().put(nodeB, 2);
            nodeF.getChild().put(nodeA, 2);
            nodeG.getChild().put(nodeC, 3);
            nodeG.getChild().put(nodeA, 5);
            nodeG.getChild().put(nodeH, 1);
            nodeH.getChild().put(nodeB, 4);
            nodeH.getChild().put(nodeG, 1);
            /**
             *  open用于存储未遍历的点
             *  close用来存储已遍历的节点
             */
            open.add(nodeB);
            open.add(nodeC);
            open.add(nodeD);
            open.add(nodeE);
            open.add(nodeF);
            open.add(nodeG);
            open.add(nodeH);
            close.add(nodeA);
            return nodeA;
        }
    }

    /*
     * Dijkstra对象用于计算起始节点到所有其他节点的最短路径
     */
    private Set<Node> open = new HashSet<Node>();//open用于存储未遍历的点
    private Set<Node> close = new HashSet<Node>();//close用来存储已遍历的节点
    private Map<String, Integer> path = new HashMap<String, Integer>();//封装路径距离
    private Map<String, String> pathInfo = new HashMap<String, String>();//封装路径信息

    public Node init() {
        //计算A到H的最短距离
        //初始节点是A
        //初始路径,因没有A->E这条路径,所以path(E)设置为Integer.MAX_VALUE
        /**
         * 以下是A节点到每个节点的距离
         */
        path.put("B", 1);
        pathInfo.put("B", "A->B[" + 1 + "]=1");//键,从哪里到哪里+权值

        path.put("C", 1);
        pathInfo.put("C", "A->C[" + 1 + "]=1");

        path.put("D", 4);
        pathInfo.put("D", "A->D[" + 4 + "]=4");

        path.put("E", Integer.MAX_VALUE);
        pathInfo.put("E", "A");

        path.put("F", 2);
        pathInfo.put("F", "A->F[" + 2 + "]=2");

        path.put("G", 5);
        pathInfo.put("G", "A->G[" + 5 + "]=5");

        path.put("H", Integer.MAX_VALUE);
        pathInfo.put("H", "A");
        //将初始节点放入close,其他节点放入open
        Node start = new MapBuilder().build(open, close);
        return start;
    }

    //计算最短路径之后把信息加入到info中
    public void computePath(Node start) {
        Node nearest = getShortestPath(start);//取距离start节点最近的子节点,放入close
        if (nearest == null) {
            return;
        }
        close.add(nearest);//最近的临近子节点,放入close集合,他已经遍历了
        open.remove(nearest);//已经遍历过了,就从open中去除
        System.out.print(start.getName() + "---->");
        Map<Node, Integer> childs = nearest.getChild();//最近节点的所有儿子

        for (Node child : childs.keySet()) {

            if (open.contains(child)) {//如果子节点在open中,说明涵盖此子节点
                System.out.print(nearest.getName() + "--->" + child.getName());
                Integer newCompute = path.get(nearest.getName()) + childs.get(child);
                System.out.println("--=" + newCompute);
                if (path.get(child.getName()) > newCompute) {//之前设置的距离大于新计算出来的距离
                    path.put(child.getName(), newCompute);//用新的替换之前设置的
                    //封装最新的路径信息
                    pathInfo.put(child.getName(),
                            //最短路径到儿子的距离
                            "" + newCompute);
                }
            }
        }
        System.out.println("again----------");
        computePath(start);//重复执行自己,确保和自己有关的所有从自己到子节点的距离都被遍历
        System.out.println("nearest----------");
        //执行完毕一个点例如A,之后执行离他最近的点B,依次递归
        computePath(nearest);//向外一层层递归,直至所有顶点被遍历
    }

    public void printPathInfo() {
        Set<Map.Entry<String, String>> pathInfos = pathInfo.entrySet();
        for (Map.Entry<String, String> pathInfo : pathInfos) {
            System.out.println(pathInfo.getKey() + ":" + pathInfo.getValue());
        }
    }

    /**
     * 获取与node最近的子节点
     */
    private Node getShortestPath(Node node) {
        Node res = null;
        int minDis = Integer.MAX_VALUE;
        Map<Node, Integer> childs = node.getChild();
        for (Node child : childs.keySet()) {
            if (open.contains(child)) {//open用于存储未遍历的点
                int distance = childs.get(child);
                if (distance < minDis) {//第一次肯定执行
                    minDis = distance;
                    res = child;
                }
            }
        }
        return res;//返回最近的节点
    }

    public static void main(String[] args) {
        DijkstraPath test = new DijkstraPath();
        Node start = test.init();
        test.computePath(start);
        System.out.println();
        System.out.println(">>>>>>>>>>>>最短路径结果>>>>>>>>>>>>>>");
        test.printPathInfo();
    }


}


      

输出:

        "C:\Program Files (x86)\Java\jdk1.8.0_73\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2019.2.3\lib\idea_rt.jar=62317:C:\Program Files\JetBrains\IntelliJ IDEA 2019.2.3\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files (x86)\Java\jdk1.8.0_73\jre\lib\charsets.jar;C:\Program Files (x86)\Java\jdk1.8.0_73\jre\lib\deploy.jar;C:\Program Files (x86)\Java\jdk1.8.0_73\jre\lib\ext\access-bridge-32.jar;C:\Program Files (x86)\Java\jdk1.8.0_73\jre\lib\ext\cldrdata.jar;C:\Program Files (x86)\Java\jdk1.8.0_73\jre\lib\ext\dnsns.jar;C:\Program Files (x86)\Java\jdk1.8.0_73\jre\lib\ext\jaccess.jar;C:\Program Files (x86)\Java\jdk1.8.0_73\jre\lib\ext\jfxrt.jar;C:\Program Files (x86)\Java\jdk1.8.0_73\jre\lib\ext\localedata.jar;C:\Program Files (x86)\Java\jdk1.8.0_73\jre\lib\ext\nashorn.jar;C:\Program Files (x86)\Java\jdk1.8.0_73\jre\lib\ext\sunec.jar;C:\Program Files (x86)\Java\jdk1.8.0_73\jre\lib\ext\sunjce_provider.jar;C:\Program Files (x86)\Java\jdk1.8.0_73\jre\lib\ext\sunmscapi.jar;C:\Program Files (x86)\Java\jdk1.8.0_73\jre\lib\ext\sunpkcs11.jar;C:\Program Files (x86)\Java\jdk1.8.0_73\jre\lib\ext\zipfs.jar;C:\Program Files (x86)\Java\jdk1.8.0_73\jre\lib\javaws.jar;C:\Program Files (x86)\Java\jdk1.8.0_73\jre\lib\jce.jar;C:\Program Files (x86)\Java\jdk1.8.0_73\jre\lib\jfr.jar;C:\Program Files (x86)\Java\jdk1.8.0_73\jre\lib\jfxswt.jar;C:\Program Files (x86)\Java\jdk1.8.0_73\jre\lib\jsse.jar;C:\Program Files (x86)\Java\jdk1.8.0_73\jre\lib\management-agent.jar;C:\Program Files (x86)\Java\jdk1.8.0_73\jre\lib\plugin.jar;C:\Program Files (x86)\Java\jdk1.8.0_73\jre\lib\resources.jar;C:\Program Files (x86)\Java\jdk1.8.0_73\jre\lib\rt.jar;C:\Users\Administrator\Desktop\newTSP\sister\out\production\sister" com.neusoft.data.structure.DijkstraPath
A---->C--->G--=4
again----------
A---->B--->F--=3
B--->H--=5
again----------
A---->F--->E--=3
again----------
A---->D--->E--=5
again----------
A---->G--->H--=5
again----------
nearest----------
G---->again----------
nearest----------
nearest----------
D---->again----------
nearest----------
nearest----------
nearest----------
nearest----------

>>>>>>>>>>>>最短路径结果>>>>>>>>>>>>>>
B:A->B[1]=1
C:A->C[1]=1
D:A->D[4]=4
E:3
F:A->F[2]=2
G:4
H:5

Process finished with exit code 0

      

分析(参考):

v2-01da125c7105dfca70bd4fd1bdaac6d0_b.jpg

v2-e2d96214798b2872d3ee477af950c127_b.jpg

发布了158 篇原创文章 · 获赞 18 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/yunfengfengfeng/article/details/105555008