package cn.like.study.algorithm; import java.util.*; /** * @program: MyCode * @description: 狄克斯特拉算法 * 算法步驟:1.判斷是否有未處理的節點 * 2.如有,得到其中離起點最近的節點 * 3.遍歷該節點全部鄰居並更行其開銷 * 4.若是有鄰居的開銷被更新,同時更新父節點 * 5.該節點標記爲已處理 * 6.重複第1步 * @author: like * @create: 2018-04-22 10:49 **/ public class Dijkstra { //設置沒有已知到達路徑的標記 private static int NOWAY_SIGN = Integer.MAX_VALUE; private static final String START = "start"; private static final String END = "end"; public void getMinStep(String start, String end, Map<String, Map<String, Integer>> graph) { //各節點的最少花費 Map<String, Integer> costs = graph.get(start); //各節點最少花費時的父節點 Map<String, String> parents = new HashMap<String, String>(); //已處理的節點 HashSet<String> processed = new HashSet<String>(); //在未處理的節點中找到開銷最小的節點 String node = findLowestCostNode(costs, processed); while (node != null && graph.get(node) != null) { int cost = costs.get(node); //遍歷當前節點的全部鄰居 Iterator iterator = graph.get(node).entrySet().iterator(); while (iterator.hasNext()) { Map.Entry<String, Integer> entry = (Map.Entry) iterator.next(); //經過node節點到該節點的最小消耗 int newCost = cost + entry.getValue(); //更新從start到該節點的最小消耗 if (!costs.containsKey(entry.getKey()) || costs.get(entry.getKey()) > newCost) { costs.put(entry.getKey(), newCost); parents.put(entry.getKey(), node); } } //該節點加入已處理 processed.add(node); //找出當前最小消耗的節點 node = findLowestCostNode(costs, processed); } printPath(parents, costs.get(END)); } public void initParents(String start, Map<String, Integer> startGraph, Map<String, String> parents) { Iterator iterator = startGraph.entrySet().iterator(); while (iterator.hasNext()) { Map.Entry<String, Integer> entry = (Map.Entry) iterator.next(); parents.put(entry.getKey(), start); } } /** * 找出未處理節點中消耗最小的節點 * * @param costs * @param processed * @return */ public String findLowestCostNode(Map<String, Integer> costs, HashSet<String> processed) { int lowestCost = NOWAY_SIGN; String lowestCostNode = null; Iterator iterator = costs.entrySet().iterator(); while (iterator.hasNext()) { Map.Entry<String, Integer> entry = (Map.Entry) iterator.next(); if (!processed.contains(entry.getKey()) && entry.getValue() < lowestCost) { lowestCost = entry.getValue(); lowestCostNode = entry.getKey(); } } return lowestCostNode; } public void printPath(Map<String, String> parents, int cost) { Stack<String> stack = new Stack<String>(); String parent = parents.get(END); while (parent != null) { if (START.equalsIgnoreCase(parent)) { stack.push(START); break; } stack.push(parent); parent = parents.get(parent); } StringBuffer path = new StringBuffer(); while (!stack.empty()) { String node = stack.pop(); if (path.length() != 0) { path.append("->"); } path.append(node); } System.out.println("最優路線:" + START + "->" + path.toString() + "->" + END); System.out.println("其開銷爲:" + cost); } public static void main(String[] args) { Map<String, Map<String, Integer>> graph = new HashMap<String, Map<String, Integer>>(); Map<String, Integer> start = new HashMap<String, Integer>(); start.put("A", 5); start.put("B", 2); graph.put(START, start); Map<String, Integer> a = new HashMap<String, Integer>(); a.put("C", 4); a.put("D", 2); graph.put("A", a); Map<String, Integer> b = new HashMap<String, Integer>(); b.put("A", 8); b.put("D", 7); graph.put("B", b); Map<String, Integer> c = new HashMap<String, Integer>(); c.put("D", 6); c.put(END, 3); graph.put("C", c); Map<String, Integer> d = new HashMap<String, Integer>(); d.put(END, 1); graph.put("D", d); Dijkstra dijkstra = new Dijkstra(); dijkstra.getMinStep(START, END, graph); } }
測試示例:java
輸出結果:node
最優路線:start->A->D->end
其開銷爲:8算法