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
分析(参考):