Bellman Ford演算法的改進 SPFA演算法

2021-06-22 05:10:50 字數 2761 閱讀 6202

一、演算法簡介

spfa演算法全稱是最短路徑快速演算法(shortest path faster algorithm

),是基於bellman-ford演算法的佇列優化。spfa演算法能和bellman-ford演算法一樣,可以處理帶負權值邊的圖,但是複雜度要小很多。

一般認為,此演算法的時間複雜度為o(ke),其中k為所有頂尖進隊的平均次數,可以證明k一般不超過2。

原來的bellman-ford演算法,對圖進行 |v|-1 次遍歷,多了很多沒有必要的操作。現在考慮用乙個佇列來優化,若頂點v的最短路徑改變了,則將此頂點入隊。下一次遍歷從該頂點出發到所有鄰接頂點的邊,進行鬆弛操作,也只將更新了最短路徑的邊入隊。

二、偽**實現

wikipedia的版本

procedure shortest-path-faster-algorithm(g, s)

1 for each vertex v ≠ s in v(g)

2 d(v) := ∞

3 d(s) := 0

4 offer s into q

5 while q is not empty

6 u := poll q

7 for each edge (u, v) in e(g)

8 if d(u) + w(u, v) < d(v) then

9 d(v) := d(u) + w(u, v)

10 if v is not in q then

11 offer v into q

三、c++實現

/*

* @ spfa.cpp

* @author halfish zhang

* @version 1.0 2014/5/24

*/#include #include #include #include using namespace std;

// 最大的頂點數

const int max_num = 2014;

// 定義常量無窮大

const int inf_num = 0x3f3f3f3f;

// 用鄰接鍊錶來儲存邊

struct edge

;// 鄰接錶用vector來儲存比較合適

vectoredges[max_num * 2];

int vertexnum, edgenum; // 實際的頂點數和邊數

int source; // 源點

int dist[max_num], pred[max_num]; // dist[i]用來存放從 source 到 i 的最短距離,pred[i]為最短路徑的前驅

bool inqueue[max_num]; // inqueue[i]存放頂點 i 是否在佇列中

int pushcount[max_num]; // pushcount[i] 表示頂點 i 被放進佇列的次數

queueq;

bool spfa()

dist[source] = 0;

// push source into queue

q.push(source);

inqueue[source] = true;

pushcount[source] = 1;

while(!q.empty())

return false;

}}

}} }

return true;

}void print(int i)

int len = s.size();

for(int i = 0; i < len; ++ i)

cout << endl << endl;

}int main(int argc, char const *argv)

if( spfa() )

else

return 0;

}

四、測試樣例

見下圖

輸入樣例:

6 9 1

1 2 7

1 3 9

1 6 14

2 3 10

2 4 15

3 4 11

3 6 2

4 5 6

5 6 9

輸出樣例

the minimum weight of these paths from 1 are:

0 7 9 20 26 11

all these paths are as follows:

the path from 1 to 1 is :

1the path from 1 to 2 is :

1 2the path from 1 to 3 is :

1 3the path from 1 to 4 is :

1 3 4

the path from 1 to 5 is :

1 3 4 5

the path from 1 to 6 is :

1 3 6

--------------------------------

process exited with return value 0

press any key to continue . . .

bellman ford演算法的理解

include include include define inf 0x3f3f3f3f using namespace std typedef struct edge edge edge edge 1100 int source,edgenum,nodenum int dist 1100 儲存源...

Bellman Ford演算法,SPFA演算法

bellman ford 演算法能在更普遍的情況下 存在負權邊 解決單源點最短路徑問題。對於給定的帶權 有向或無向 圖g v,e 其源點為 s,加權函式w是 邊集e 的對映。對圖g執行 bellman ford 演算法的結果是乙個布林值,表明圖中是否存在著乙個從源點s 可達的負權迴路。若不存在這樣的...

Bellman ford 演算法詳解

昨天說的dijkstra固然很好用,但是卻解決不了負權邊,想要解決這個問題,就要用到bellman ford.我個人認為bellman ford比dijkstra要好理解一些,還是先上資料 有向圖 5 712 8135 23 6 5 4 324 735 2 45 3 在講述開,先設幾個陣列 orig...