算法——迪克斯特拉算法

迪克斯特拉算法主要分四個步驟:

  1. 找到“最便宜”的節點(可在最短時間內到達的節點)。
  2. 更新該節點的鄰居節點的開銷。
  3. 重複這個過程,直到對圖中每個節點都做了。
  4. 計算最終路徑。

這個算法的核心理念是:找到圖中最便宜的節點,並確保沒有到該節點更便宜的路徑。 (所以需要注意的是如果你的圖包含負權邊,就不能用這個算法,因爲這會導致已經處理過的節點更新。)

假設我現在有上面的一張圖,計算A->F的最小權重。

步驟一:

從A可以到B,C,F。相應的權重爲:

A->B 8
A->C 10
A->F 100

步驟二:

由步驟一得出由A->B爲當前的最便宜節點,然後找到它相鄰的節點:

B->D 10
B->E 70

由此可以更新A->D和A->E的權重:

A->D 18
A->E 78

步驟三:

重複這個操作:

C->E:

C->E 30

更新最短權重:

A->D 18
A->E 40

A->F:

A->F 100

當前最短權重爲:

A->D 18
A->E 40
A->F 100

由D->F可以得到65,A->D爲18,更新權重表:

A->E 40
A->F 83

由E->F可以得到45,A->E爲40,更新權重表:

A->F 83

步驟4:

最後就可以得到它的最小權重路徑:A->B->D->F:83

代碼實現:

import java.util.*;

class Node {
    String name;
    int val;
    Map<String, Node> map;

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

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

    public Node() {

    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getVal() {
        return val;
    }

    public void setVal(int val) {
        this.val = val;
    }

    public Map<String, Node> getMap() {
        return map;
    }

    public void setMap(Map<String, Node> map) {
        this.map = map;
    }

    public static void main(String[] args) {
        Node A = new Node("A");


        //構建A
        Map<String, Node> map = new HashMap<>();
        map.put("B", new Node("B", 8));
        map.put("F", new Node("F", 100));
        map.put("C", new Node("C", 10));
        A.setMap(map);
        //構建B
        Node B = A.getMap().get("B");
        map = new HashMap<>();
        map.put("D", new Node("D", 10));
        map.put("E", new Node("E", 70));
        B.setMap(map);
        //構建C
        Node C = A.getMap().get("C");
        map = new HashMap<>();
        map.put("E", new Node("E", 30));
        C.setMap(map);
        //構建D
        Node D = A.getMap().get("B").getMap().get("D");
        map = new HashMap<>();
        map.put("F", new Node("F", 65));
        D.setMap(map);
        //構建BE
        Node BE = A.getMap().get("B").getMap().get("E");
        map = new HashMap<>();
        map.put("F", new Node("F", 45));
        BE.setMap(map);
        //構建CE
        Node CE = A.getMap().get("C").getMap().get("E");
        map = new HashMap<>();
        map.put("F", new Node("F", 45));
        CE.setMap(map);

        //記錄存值
        Map<String, Integer> DateMap = new HashMap<>();
        //隊列
        List<Node> list = new ArrayList<>();
        //獲取A節點下的所有節點
        getListNode(list, A);
        //記錄A節點下的值(可能A-F就是最短路徑)
        int count = list.size();
        //只要列表不爲空
        while (list.size() > 0) {
            //每次減一
            --count;
            Node node = list.get(0);
            //獲取這個這個節點的子節點
            List<Node> chiNode = new ArrayList<>();
            getListNode(chiNode, node);
            //只記錄A到子節點值
            if (DateMap.get("A" + node.getName()) == null && count >= 0) {
                DateMap.put("A" + node.getName(), node.getVal());
            }
            if (!chiNode.isEmpty()) {
                for (Node n : chiNode) {
                    if (DateMap.get("A" + n.getName()) != null) {
                        if (DateMap.get("A" + n.getName()) > (DateMap.get("A" + node.getName()) + n.getVal())) {
                            DateMap.put("A" + n.getName(), (DateMap.get("A" + node.getName()) + n.getVal()));
                        }
                    } else {
                        //添加值
                        DateMap.put("A" + n.getName(), node.getVal() + n.getVal());
                        DateMap.put(node.getName() + n.getName(), n.getVal());
                    }
                }
            }
            //獲取這個節點下的子節點
            getListNode(list, node);
            //刪除
            list.remove(0);
        }
        System.out.println(DateMap.get("AF"));
    }

    public static void getListNode(List<Node> list, Node node) {
        Map<String, Integer> map = new HashMap<>();
        if (node.getMap() != null) {
            //獲取這個節點的所有子節點
            for (String name : node.getMap().keySet()) {
                map.put(name, node.getMap().get(name).getVal());
            }
            //排序
            List<Map.Entry<String, Integer>> arrayList = new ArrayList<>(map.entrySet());
            Collections.sort(arrayList, new Comparator<Map.Entry<String, Integer>>() {
                @Override
                public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
                    return o1.getValue().compareTo(o2.getValue());
                }
            });
            //添加節點到末尾
            for (Map.Entry<String, Integer> entry : arrayList) {
                list.add(node.getMap().get(entry.getKey()));
            }
        }
    }


}

再來一個圖試試:

import java.util.*;

class Node {
    String name;
    int val;
    Map<String, Node> map;

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

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

    public Node() {

    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getVal() {
        return val;
    }

    public void setVal(int val) {
        this.val = val;
    }

    public Map<String, Node> getMap() {
        return map;
    }

    public void setMap(Map<String, Node> map) {
        this.map = map;
    }

    public static void main(String[] args) {
        Node A = new Node("A");

        //構建A
        Map<String, Node> map = new HashMap<>();
        map.put("B", new Node("B", 10));
        map.put("D", new Node("D", 20));
        map.put("C", new Node("C", 10));
        A.setMap(map);
        //構建B
        Node B = A.getMap().get("B");
        map = new HashMap<>();
        map.put("F", new Node("F", 5));
        map.put("E", new Node("E", 20));
        B.setMap(map);
        //構建C
        Node C = A.getMap().get("C");
        map = new HashMap<>();
        map.put("F", new Node("F", 20));
        C.setMap(map);
        //構建D
        Node D = A.getMap().get("D");
        map = new HashMap<>();
        map.put("E", new Node("E", 30));
        map.put("G", new Node("G", 100));
        D.setMap(map);

        //構建BE
        Node BE = A.getMap().get("B").getMap().get("E");
        map = new HashMap<>();
        map.put("G", new Node("G", 50));
        BE.setMap(map);
        //構建BF
        Node BF = A.getMap().get("B").getMap().get("F");
        map = new HashMap<>();
        map.put("G", new Node("G", 20));
        BF.setMap(map);

        //構建CF
        Node CF = A.getMap().get("C").getMap().get("F");
        map = new HashMap<>();
        map.put("G", new Node("G", 20));
        CF.setMap(map);

        //構建CE
        Node DE = A.getMap().get("D").getMap().get("E");
        map = new HashMap<>();
        map.put("G", new Node("G", 30));
        DE.setMap(map);


        //記錄存值
        Map<String, Integer> DateMap = new HashMap<>();
        //隊列
        List<Node> list = new ArrayList<>();
        //獲取A節點下的所有節點
        getListNode(list, A);
        //記錄A節點下的值(可能A-F就是最短路徑)
        int count = list.size();
        //只要列表不爲空
        while (list.size() > 0) {
            //每次減一
            --count;
            Node node = list.get(0);
            //獲取這個這個節點的子節點
            List<Node> chiNode = new ArrayList<>();
            getListNode(chiNode, node);
            //只記錄A到子節點值
            if (DateMap.get("A" + node.getName()) == null && count >= 0) {
                DateMap.put("A" + node.getName(), node.getVal());
            }
            if (!chiNode.isEmpty()) {
                for (Node n : chiNode) {
                    if (DateMap.get("A" + n.getName()) != null) {
                        if (DateMap.get("A" + n.getName()) > (DateMap.get("A" + node.getName()) + n.getVal())) {
                            DateMap.put("A" + n.getName(), (DateMap.get("A" + node.getName()) + n.getVal()));
                        }
                    } else {
                        //添加值
                        DateMap.put("A" + n.getName(), node.getVal() + n.getVal());
                        DateMap.put(node.getName() + n.getName(), n.getVal());
                    }
                }
            }
            //獲取這個節點下的子節點
            getListNode(list, node);
            //刪除
            list.remove(0);
        }
        System.out.println(DateMap.get("AG"));
    }

    public static void getListNode(List<Node> list, Node node) {
        Map<String, Integer> map = new HashMap<>();
        if (node.getMap() != null) {
            //獲取這個節點的所有子節點
            for (String name : node.getMap().keySet()) {
                map.put(name, node.getMap().get(name).getVal());
            }
            //排序
            List<Map.Entry<String, Integer>> arrayList = new ArrayList<>(map.entrySet());
            Collections.sort(arrayList, new Comparator<Map.Entry<String, Integer>>() {
                @Override
                public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
                    return o1.getValue().compareTo(o2.getValue());
                }
            });
            //添加節點到末尾
            for (Map.Entry<String, Integer> entry : arrayList) {
                list.add(node.getMap().get(entry.getKey()));
            }
        }
    }


}

        Node A = new Node("A");

        //構建A
        Map<String, Node> map = new HashMap<>();
        map.put("B", new Node("B", 5));
        map.put("C", new Node("C", 2));
        A.setMap(map);
        //構建B
        Node B = A.getMap().get("B");
        map = new HashMap<>();
        map.put("D", new Node("D", 4));
        map.put("E", new Node("E", 2));
        B.setMap(map);
        //構建C
        Node C = A.getMap().get("C");
        map = new HashMap<>();
        map.put("E", new Node("E", 7));
        map.put("B", new Node("B", 8));
        C.setMap(map);

        //構建BE
        Node BE = A.getMap().get("B").getMap().get("E");
        map = new HashMap<>();
        map.put("F", new Node("F", 1));
        BE.setMap(map);
        Node BD = A.getMap().get("B").getMap().get("D");
        map = new HashMap<>();
        map.put("F", new Node("F", 3));
        map.put("E", new Node("E", 6));
        BD.setMap(map);
        Node BDE = A.getMap().get("B").getMap().get("D").getMap().get("E");
        map = new HashMap<>();
        map.put("F", new Node("F", 1));
        BDE.setMap(map);

        //構建CF
        Node CE = A.getMap().get("C").getMap().get("E");
        map = new HashMap<>();
        map.put("F", new Node("F", 1));
        CE.setMap(map);
        Node CB = A.getMap().get("C").getMap().get("B");
        map = new HashMap<>();
        map.put("D", new Node("D", 4));
        map.put("E", new Node("E", 2));
        CB.setMap(map);
        Node CBD = A.getMap().get("C").getMap().get("B").getMap().get("D");
        map = new HashMap<>();
        map.put("F", new Node("F", 3));
        map.put("E", new Node("E", 6));
        CBD.setMap(map);
        Node CBDE = A.getMap().get("C").getMap().get("B").getMap().get("D").getMap().get("E");
        map = new HashMap<>();
        map.put("F", new Node("F", 1));
        CBDE.setMap(map);
        Node CBE = A.getMap().get("C").getMap().get("B").getMap().get("E");
        map = new HashMap<>();
        map.put("F", new Node("F", 1));
        CBE.setMap(map);

 

OK~迪克斯特拉算法的實現!!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章