nsga2算法c++实现_Bellman-Ford算法
相關(guān)文章
圖論-圖的構(gòu)建
深度優(yōu)先搜索遍歷圖
廣度優(yōu)先搜索遍歷圖
單源最短路徑之Dijkstra算法
貪心算法如何貪心
貝爾曼-福特算法
貝爾曼-福特算法(Bellman-Ford)是由理查德·貝爾曼(Richard Bellman) 和 萊斯特·福特 創(chuàng)立的,求解單源最短路徑問題的一種算法。
有時候這種算法也被稱為 Moore-Bellman-Ford 算法,因為 Edward F. Moore 也為這個算法的發(fā)展做出了貢獻。
它的原理是對圖進行V-1次松弛操作(V是頂點數(shù)量),得到所有可能的最短路徑。
其優(yōu)于Dijkstra算法的方面是邊的權(quán)值可以為負數(shù)、實現(xiàn)簡單,缺點是時間復雜度過高,高達O(VE)。但算法可以進行若干種優(yōu)化,提高了效率。
貝爾曼-福特算法與迪科斯徹算法類似,都以松弛操作為基礎(chǔ),即估計的最短路徑值漸漸地被更加準確的值替代,直至得到最優(yōu)解。
在兩個算法中,計算時每個邊之間的估計距離值都比真實值大,并且被新找到路徑的最小長度替代。
然而,迪科斯徹算法以貪心法選取未被處理的具有最小權(quán)值的節(jié)點,然后對其出邊進行松弛操作;
而貝爾曼-福特算法簡單的對所有邊進行松弛操作,共V-1次,其中V是圖的頂點數(shù)量。
在重復地計算中,已計算得到正確的距離的邊的數(shù)量不斷增加,直到所有邊都計算得到了正確的路徑。
這樣的策略使得貝爾曼-福特算法比迪科斯徹算法適用于更多種類的輸入
實現(xiàn)過程
從上面介紹我們可以知道,Bellman算法對每一條邊采用松弛操作,對于單源最短路徑實現(xiàn)來說,
源點到某一頂點所經(jīng)過的邊最多為V-1條(可以看成樹的兩個結(jié)點),如下,三個頂點ABC,A->C最多走過2兩條邊即A->B->C
A->BA->CB->C在我們將源點最短路徑設(shè)置為0時,每次松弛操作,**至少會松弛一條邊**,而最多共有N-1條邊,所以我們需要遍歷N-1次。
每一次遍歷的松弛操作和Dijkstra算法類似,判斷結(jié)點u權(quán)重是否大于 v->u的權(quán)重+v的權(quán)重。
與Dijkstra算法使用最短邊向其他頂點擴展方案不同,在Bellman-Ford算法中松弛操作是針對邊,其目的是對每一條邊進行松弛,
這樣總能使得邊達到最小,如下圖解,A為源點
A->C 2D->C 1A->B -1B->D 1上面共計 4個頂點,源點A到達任意頂點B,C,D最高走V-1=3條邊,也就是松弛3輪,
初始化時源點A到任意頂點設(shè)置為無窮大,s[]表示最短距離,S[A]=0。
那么第一輪:
A -> C 邊權(quán)2 可以推導==> (S[C] = ∞) > (S[A] + W[AB] = 0+2)條件符合,所以進行松弛操作 S[C] = 2
D -> C 邊權(quán)1 可以推導==> (S[C] = 2) > (S[D] + W[DC] = ∞+1)條件不符合,無法進行松弛操作
A -> B 邊權(quán)-1 可以推導==> (S[B] = ∞) > (S[A] + W[AB] = 0+(-1))條件符合,所以進行松弛操作 S[B] = -1
B -> D 邊權(quán)1 可以推導==> (S[D] = ∞) > (S[B] + W[BD] = -1+1)條件符合,所以進行松弛操作 S[D] = 0
然后進行第二輪(基于第一輪):
A -> C 邊權(quán)2 可以推導==> (S[C] = 2) > (S[A] + W[AB] = 0+2)條件不符合,無法進行松弛操作
D -> C 邊權(quán)1 可以推導==> (S[C] = 2) > (S[D] + W[DC] = 0+1)條件符合,所以進行松弛操作 S[C] = 1
A -> B 邊權(quán)-1 可以推導==> (S[B] = -1) > (S[A] + W[AB] = 0+(-1))條件不符合,無法進行松弛操作
B -> D 邊權(quán)1 可以推導==> (S[D] = 0) > (S[B] + W[BD] = -1+1)條件不符合,無法進行松弛操作
第三輪邏輯同上。
我們會發(fā)現(xiàn)其實第二輪的時候,已經(jīng)實現(xiàn)最短路徑了,第三輪屬于沒有用的遍歷。
負環(huán)
負環(huán),又叫負權(quán)回路,負權(quán)環(huán),指的是一個圖中存在一個環(huán),里面包含的邊的邊權(quán)總和<0。在存在負環(huán)的圖中,是求不出最短路徑的,
因為每次要在這個環(huán)上遍歷,最短路徑就會無限次的變小。如下
A->B 1A->C 1C->B -1B->D 1D->C 1那么BCD就會存在負環(huán),按照上面N-1次遍歷后,我們再遍歷,最短路徑仍會變小。
實現(xiàn)代碼(C++)
main.cpp// Bellman-Ford Created by 陳龍.// Copyright ? 2019 陳龍. All rights reserved.//#include using namespace std;//頂點和邊和源點int N,E,S; struct Graph{ //起點,終點 int u,v; int w;// Graph(int _u,int _v,int _w):u(_u),v(_v),w(_w){};};int main(int argc, const char * argv[]) { // insert code here... cin>>N>>E>>S; Graph g[N]; int dis[N]; int u,v,w; for (int i=0; i>u>>v>>w; g[i].u = u; g[i].v=v; g[i].w=w; } //初始化 dis[S] = 0; for(int i=0;i g[j].w + dis[g[j].u]) { dis[g[j].v] =g[j].w + dis[g[j].u]; } } } // 判斷是否有負環(huán)路 for(int i=0; i dis[g[i].u] + g[i].w){ cout<總結(jié)
以上是生活随笔為你收集整理的nsga2算法c++实现_Bellman-Ford算法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 固件类型bios好还是uefi好_uef
- 下一篇: C++PrimerPlus学习——第十三