圖算法

最小距離相關算法

Dijkstra算法 單源最短路徑算法 路徑大於零

1.定義概覽

Dijkstra(迪傑斯特拉)算法是典型的單源最短路徑算法,用於計算一個節點到其他所有節點的最短路徑。主要特點是以起始點爲中心向外層層擴展,直到擴展到終點爲止。Dijkstra算法是很有代表性的最短路徑算法,在很多專業課程中都作爲基本內容有詳細的介紹,如數據結構,圖論,運籌學等等。注意該算法要求圖中不存在負權邊。

問題描述:在無向圖 G=(V,E) 中,假設每條邊 E[i] 的長度爲 w[i],找到由頂點 V0 到其餘各點的最短路徑。(單源最短路徑)

2.算法步驟

2.1 算法思想

首先初始整個帶權重的有向圖G=(N,E).然後在將所有節點分成兩個集合 S(表示已經算計完畢的節點,初始爲發起節點,值爲0)、U(表示未確定的節點列表,初始爲 除了初始節點之外的節點,值爲無限大)。按照最短路徑從U裏面的節點移動到S裏面,必須保證U中的任意節點到原始節點的距離大於S中的任意節點到原始節點的距離。

2.2 算法步驟

  1. 初始化圖,u爲原始節點、S爲已處理節點{u=0}、U未處理節點{除了u其它節點=無限大}。將u設置爲當前節點`u
  2. 遍歷U裏面所有節點到`u 距離`d,如果節點不與`u直連則`爲無限大。判斷U裏面的每個節點當前距離是否大於 `d + `u到u的距離,大於就替換
  3. 選擇U裏面節點的距離最小的節點,移動到S。 並將其設置爲 `u
  4. 重複2,3 兩個步驟,直到計算完所有節點。

2.3 算法可視化

圖片描述

3.代碼

3.1 java + guava

import com.google.common.graph.ImmutableValueGraph;
import com.google.common.graph.MutableValueGraph;
import com.google.common.graph.ValueGraphBuilder;
import lombok.extern.slf4j.Slf4j;

import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

@Slf4j
public class DijkstraTest {
    public static void main(String[] args) {
        // init
        MutableValueGraph<Integer, Integer> init = ValueGraphBuilder.undirected().build();

        init.putEdgeValue(1, 2, 7);
        init.putEdgeValue(2, 3, 10);
        init.putEdgeValue(1, 3, 9);
        init.putEdgeValue(1, 6, 14);
        init.putEdgeValue(2, 4, 15);
        init.putEdgeValue(3, 6, 2);
        init.putEdgeValue(3, 4, 11);
        init.putEdgeValue(6, 5, 9);
        init.putEdgeValue(5, 4, 6);
        ImmutableValueGraph<Integer, Integer> graph = ImmutableValueGraph.copyOf(init);


        //1.
        Map<Integer, Integer> S = new HashMap<>();
        Map<Integer, Integer> U = new HashMap<>();
        int u = 1;
        S.put(1, 0);
        for (int i = 2; i <= 6; i++) {
            U.put(i, Integer.MAX_VALUE);
        }

        // 2.
        for (; ; ) {

            Integer finalU = u;
            graph.adjacentNodes(u).stream().filter(U::containsKey).forEach(node -> {
                Optional<Integer> value = graph.edgeValue(finalU, node);
                if (value.get() + S.get(finalU) < U.get(node)) {
                    U.put(node, value.get());
                }
            });
            // 3.
            Optional<Map.Entry<Integer, Integer>> min = U.entrySet().stream().min(Comparator.comparing(Map.Entry::getValue));
            u = min.get().getKey();
            S.put(u, min.get().getValue());
            U.remove(u);
            log.info("{},{}", S, U);
            if (U.isEmpty()) {
                break;
            }
            // 4.
        }
        log.info("result {}", S);


    }
}

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