Dijkstra與Floyd求取最短路徑

2021-10-03 20:29:20 字數 3268 閱讀 9982

最短路徑演算法:用於計算乙個節點到其他所有節點的最短路徑。是圖論研究中的乙個經典演算法問題。

一、dijkstra演算法:

典型的最短路徑路由演算法,用於計算乙個節點到其他所有節點的最短路徑。主要特點是以起始點為中心向外層層擴充套件,直到擴充套件到終點為止。dijkstra演算法能得出最短路徑的最優解,但由於遍歷計算的節點很多,所以效率低。可以用堆優化。

按照路徑長度遞增的次序一步步併入來求取,是貪心演算法的乙個應用,用來解決單源點到其餘頂點的最短路徑問題。使用了廣度優先搜尋bfs解決賦權有向圖或者無向圖的單源最短路徑問題,演算法最終得到了乙個最短路徑樹。

演算法思想:

兩個集合p、q,p中存放已經確定最短路徑的結點,q中存放未確定的;兩個陣列dis、t,dis中用於存放從起點到該結點的最短路徑值,t用於標識該節點是否在集合p中,在為1,否則為0;

1)首先將起點加入集合p中,其餘節點放在q中,起點的dis為0,其餘節點為無窮大。

2)遍歷一次獲取起點v到各個節點的距離,更新dis;

3)得到距離最短的結點x,將其加入p中,表示從起點v到x的最短距離已經確定;

4)計算該結點到其餘節點的距離,判斷dis[i]與dis[x]+(x, i)的距離,如果距離更小則更新dis值;這叫做鬆弛。

5)更新dis後,選出最小的dis,將該結點加入p集合,在一次重複以上步驟,知道q集合中的所有結點的最短路徑值都已經得到,則演算法結束。

實現:1、基於鄰接矩陣

public class dijkstra 

}} //更新起點到各個節點的距離

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

//表明該節點已經計算過最短距離

st[v] = true;

//處理從起點到其餘節點的距離

for(int i = 0; i < numofvexs; i++)}}

// 找到源點到索引index頂點的最短路徑長度

if(index != -1)

// 更新當前最短路徑及距離

for(int w = 0; w < numofvexs; w++)}}

} return distance;

}}

2、基於鄰接表

public class dijkstra 

//鄰接表中表的頂點

private class vnode

private int numofvexs;//節點數

private vnode vexs;//頂點陣列

public int dijkstra2(int v)

enode current;

current = vexs[v].firstadj;

while (current != null)

distance[v] = 0;

st[v] = true;

// 處理從源點到其餘頂點的最短路徑

for (int i = 0; i < numofvexs; i++) }}

// 找到源點到索引為index頂點的最短路徑長度

if (index != -1)

st[index] = true;

// 更新當前最短路徑及距離

for (int w = 0; w < numofvexs; w++)

if (st[w] == false)

current = current.nextadj;}}

} return distance;

}}

二、floyd演算法

又稱為插點法,是一種用動態規劃的思想尋找給定的加權圖中多源點之間最短路徑的演算法。我們可以求出任意兩個點之間最短路徑。時間複雜度為o(n^3)。floyd-warshall演算法不能解決帶有「負權迴路」的圖。

演算法特點:floyd是解決任意兩點間的最短路徑的一種演算法,可以正確處理有向圖或無向圖或負權的最短路徑問題(但不能存在負權迴路),同時也被用於計算有向圖的傳遞閉包。

演算法思路:

通過floyd計算圖g =(v,e)中各個頂點的最短路徑時,需要引入兩個矩陣,矩陣d中的元素d[i][j]表示頂點i(第i個頂點)到頂點j(第j個頂點)的距離。矩陣p中的元素p[i][j],表示頂點i到頂點j經過了p[i][j]記錄的值所表示的頂點,也就是說i到j需要經過中間點p[i][j]。

假設圖g中頂點個數為n,則需要對矩陣d和矩陣p進行n次更新。初始時,矩陣d中頂點d[i][j]的距離為頂點i到頂點j的權值;如果i和j不相鄰,則d[i][j]=∞,矩陣p的值為頂點p[i][j]的j的值。

接下來開始,對矩陣d進行n次更新。

1)第1次更新時,如果」d[i][j]的距離」 > 「d[i][0]+d[0][j]」(d[i][0]+d[0][j]表示」i與j之間經過第1個頂點的距離」),則更新d[i][j]為」d[i][0]+d[0][j]」,更新p[i][j]=p[i][0],也就是將0這個節點存入。

2)同理,第k次更新時,如果」d[i][j]的  距離」 > 「d[i][k-1]+d[k-1][j]」,則更新d[i][j]為」d[i][k-1]+d[k-1][j]」,p[i][j]=p[i][k-1]。更新n次之後,操作完成。

演算法實現:

public class floyd 

public void floydfunction(int distance,int paths)}}

}system.out.printf("floyd演算法執行後 distance: \n");

print(distance);

system.out.printf("floyd演算法執行後 paths: \n");

print(paths);

}// 列印floyd最短路徑的結果

public void print(int distance)

}public static void main(string args),,};

char nodes=;

floyd floyd=new floyd(matrix,nodes);

//長度陣列。即,dist[i][j]=sum表示,"頂點i"到"頂點j"的最短路徑的長度是sum。

int distance=new int[nodes.length][nodes.length];

//路徑。path[i][j]=k表示,"頂點i"到"頂點j"的最短路徑會經過頂點k。

int paths=new int[nodes.length][nodes.length];

floyd.floydfunction(distance,paths);

}}

Dijkstra演算法與Floyd演算法

給定一定無負值圈的圖g,頂點集為v,使用dijkstra演算法求出g中頂點n到頂點m的最短路徑,使用floyd演算法求出多源的最短路徑,具體的圖如下 dijkstra演算法又稱為單源最短路徑,所謂單源是在乙個有向圖中,從乙個頂點出發,求該頂點至所有可到達頂點的最短路徑問題。include inclu...

Dijkstra和Floyd演算法

floyd 演算法 如果要求所有兩結點間的最短路徑,則可以使用 dijkstra演算法n 次完成,時間複雜度是 o n 3 floyd 還提出過另乙個演算法,同樣是 o n 3 的複雜度,但形式上更簡單些。要求的解是乙個矩陣 n n 其中s i j 表示結點i到 j的最短路徑,演算法很像動態 規劃演...

Dijkstra和Floyd演算法

floyd演算法 如果要求所有兩結點間的最短路徑,則可以使用dijkstra演算法n次完成,時間複雜度是 o n 3 floyd還提出過另乙個演算法,同樣是o n 3 的複雜度,但形式上更簡單些。要求的解是乙個矩陣 n n 其中s i j 表示結點i到j的最短路徑,演算法很像動態 規劃演算法,甚至更...