利用分支限界法求解單源最短路(Dijkstra)問題


分支限界法定義:采用Best fist search算法,並使用剪枝函數的算法稱為分支界限法。

分支限界法解釋:按Best first的原則,有選擇的在其child中進行擴展,從而舍棄不含有最優解的分支,不斷重復這一過程,直到找到答案或者判定無解。

分支界限法常常用到優先隊列來選擇最佳擴展節點,有時也會用到普通隊列,以先進先出為原則來進行篩選。

單源最短路問題定義:給定有向圖和起點,尋找到達所有點的最短路徑。

單源最短路的分支限界法概述:首先把節點加入優先隊列,以到當前節點的最短路為下界,之后不斷地從隊列中取出最優擴展點,觀察其可抵達的所有目標節點。

若當前消耗大於等於全局上界及目標節點消耗,則放棄該節點。所示代碼因沒有規定終點,即每個點都要輸出最小路徑,則不檢查這一步。

若當前路徑消耗+兩節點間路徑消耗<目標節點目前最小消耗(即更新后下界<目標當前下界)
則用不等式左邊的和替換掉右邊的值,並將該目標節點加入優先隊列。

循環這個過程直到隊列為空,即可獲得圖中所有節點的最短路。

代碼如下:

#include <queue>
#include <vector>

const int MAX_V = 100;//最大頂點數
const int INF = 100000;//正無窮
int cost[MAX_V][MAX_V];//節點間cost表(即圖)
int d[MAX_V], V, s;//起點到各個頂點的距離,頂點數,起點
//自定義優先隊列less比較函數
struct cmp
{
    bool operator()(int &a, int &b) const
    {
        //因為優先出列為greater,所以反向定義實現最小值優先
        return d[a] > d[b];
    }
};
void Dijkstra()
{
    std::priority_queue<int, std::vector<int>, cmp> pq;
    pq.push(s);
    d[s] = 0;
    while (!pq.empty())
    {
        int tmp = pq.top();pq.pop();
        for (int i = 0;i < V;++i)
        {
            if (d[i] > d[tmp] + cost[tmp][i])
            {
                d[i] = d[tmp] + cost[tmp][i];
                pq.push(i);
            }
        }
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM