最短路徑算法

場景

  • 給定帶權網絡G,遠點s 對於所有的其他頂點v, s到v的最短通路是多少?該通路由哪些邊構成

性質

  • 單調性
    • 最短路徑樹上的任一頂點v到必定是源點s到v的最短路徑
  • 歧義性
    • 最短路徑可能不唯一
  • 無環性

和最小支撐樹的區別

  • 最小支撐樹求的是整個拓撲圖的所有路徑之和最小,不能保證任意兩點之間的路徑最小 應用場景: 快遞車將霍送到城市的每一個快遞點,不走重複的路而且時間最短
  • 最短路徑是保證源點到任一一點的路徑最短 應用場景: 地圖尋徑,怎麼確保可以最短時間到達想要去的地方

代碼實現


// 最短路徑算法
template <typename Tv, typename Te> struct DijkstraPU{
    // 重載()
    virtual void operator()(Graph<Tv, Te>* graph, int v int u) {
        // 針對未發現鄰接頂點
        if (graph->status(u) != UNDISCOVER) {
            return;
        }

        // 因爲只針對兩點之間最短,所以此處和父級優先級樹和邊權重之和比較
        if (graph->priority(u) > graph->priority(v) + graph->weight(v, u)) {
            graph->priority(u) = graph->priority(v) + graph->weight(v, u)
            graph->parent(u) = v;
        }
    }
};

    // 優先級搜索算法
    template <typename PU> void pfs(int v, PU prioUpdater){
        // 重置圖狀態
        reset();

        // 時間標籤
        int clock = 0;
        int s = v;

        // 遍歷所有頂點
        do {
            // 所有未發現的頂點執行優先級搜索算法
            if (status(v) == UNDISCOVERED) {
                PFS(v, prioUpdater);
            }

            // 迭代到下一頂點
            v = ++v%n;
        } while (s != v);
    }

    // 連通域 優先級搜索框架
    template <typename PU> void PFS(int v, PU prioUpdater) {
        // 更新頂點優先級,狀態
        priority(v) = 0; // 最高優先級
        status(v) = VISITED;

        // 起點s加入遍歷樹中
        parent(s) = -1;

        // 遍歷所有頂點
        while(true) {
            // 更新當前頂點的鄰接頂點的優先級數和父級頂點
            for (int w = firstNbr(s); w > -1 ; w = nextNbr(s, w)) {
                prioUpdater(this,s, w);
            }

            // 獲取尚未加入遍歷樹中的所有頂點中優先級數最小的頂點
            int shortest = INT_MAX;
            for (int w =0; w < n ; w++) {
                if (status(w) == UNDISCOVERED && priority(w) < shortest) {
                    shortest = priority(w);
                    s = w;
                }
            }

            // TODO 自定義一些事情

            // 所有頂點都已經遍歷過了
            if (status(s) == VISITED) {
                break;
            }

            // 更新當前頂點的狀態
            status(s) = VISITED;
            type(parent(s), s) = TREE;
        }
    }

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