一、簡介
迪傑斯特拉算法是由荷蘭計算機科學家狄克斯特拉於1959 年提出的,因此又叫狄克斯特拉算法。是從一個頂點到其餘各頂點的最短路徑算法,解決的是有權圖中最短路徑問題。狄克斯特拉算法主要特點是以起始點爲中心向外層層擴展,直到擴展到終點爲止。
狄克斯特拉算法解決了有向圖最短路徑的問題。
二、實現思路
狄克斯特拉算法的實現大致可分爲四個步驟:
1. 找出有向圖中最便宜的節點
2.更新節點的鄰居,判斷有沒有到下一個節點開銷更少的路徑
3.如果有就更新該節點的開銷及其父節點
4.如果沒有,則判斷之後還有沒有其他相鄰的節點,有則繼續第一步操作,否則返回結果
以下圖爲例
要實現查找上圖節點中開銷最小的路徑我們還需要三個散列表(記錄節點狀態)和一個集合(記錄已經處理過的節點)
記錄所有節點的開銷與鄰居 記錄當前節點的開銷信息 記錄當前節點的父子關係
記錄所有已經處理過的節點
三、實現代碼
// 記錄所有已經處理過的節點
private static List<String> fileNode = new ArrayList<>();
public static void main(String[] args) {
Map<String,Map<String,Integer>> parent = new HashMap<>();
Map<String,Integer> node = new HashMap<>();
node.put("A",6);
node.put("B",2);
parent.put("start",node);
HashMap<String, Integer> mapA = new HashMap<>();
mapA.put("end",1);
parent.put("A",mapA);
HashMap<String, Integer> mapB = new HashMap<>();
mapB.put("end",5);
mapB.put("A",3);
parent.put("B",mapB);
parent.put("end",new HashMap<>());
Map<String,String> toFinal = new HashMap<>();
toFinal.put("A","start");
toFinal.put("B","start");
toFinal.put("end","none");
Map<String,Integer> costs = new HashMap<>();
costs.put("A",6);
costs.put("B",2);
costs.put("end",Integer.MAX_VALUE);
Map<String, String> method = method(parent,toFinal,costs);
Set<String> set = method.keySet();
for (String key : set) {
System.out.println(key+":"+method.get(key));
}
}
public static Map<String,String> method( Map<String,Map<String,Integer>> totalNode,Map<String,String> toFinal,Map<String,Integer> costs){
// 找出最便宜的節點
String lowestNode = getLowestNode(costs);
// 判斷當前節點是否爲終點
while (!"end".equals(lowestNode)){
// 如果當前節點不是終點 則獲取當前節點的開銷
Integer nodeNum = costs.get(lowestNode);
// 獲取當前節點所有鄰居
Map<String, Integer> lowesNodes = totalNode.get(lowestNode);
Set<String> nodes = lowesNodes.keySet();
for (String node : nodes) {
// 計算前往當前節點路徑的總開銷
Integer newNum = nodeNum + lowesNodes.get(node);
// 判斷前往節點的開銷,找出開銷少的節點
if (costs.get(node) > newNum){
// 更新當前節點的開銷
costs.put(node,newNum);
// 更新當前節點的父節點
toFinal.put(node,lowestNode);
}
}
// 將已經處理過的節點添加到記錄板
fileNode.add(lowestNode);
// 找出最便宜的節點
lowestNode = getLowestNode(costs);
}
// 返回結果
return toFinal;
}
// 找出未處理且最便宜的節點
public static String getLowestNode(Map<String,Integer> costs){
String lowestNode = null;
Integer lowest = Integer.MAX_VALUE;
if (costs != null){
Set<String> keySet = costs.keySet();
for (String nodeKey : keySet) {
Integer num = costs.get(nodeKey);
if (num < lowest && !fileNode.contains(nodeKey)) {
lowest = num;
lowestNode = nodeKey;
}
}
}
return lowestNode;
}