數據結構與算法15:單源最短路徑弗洛伊德Floyd算法

數據結構與算法15:單源最短路徑弗洛伊德Floyd算法

另一個最短路徑算法:迪傑斯特拉Dijkstra算法

    Floyd算法是另一種經典的最短路徑算法,不同的是,dijkstra算法僅計算了一個起點出發的最短路徑,而floyd算法可以計算全部節點到其他節點的最短路徑。相比之下,Floyd算法複雜度爲n3,而dijkstra算法爲n2。Floyd算法的基本思想也是鬆弛。這是一個動態規劃的經典例子,在求解各個點到其他點的最短路徑的過程中往往會有很多的重疊問題,通過一個表D[][]將這些問題保存下來,節省了重複的計算。

    這個算法看起來非常簡潔。Floyd算法第k次迭代後得到的中間結果的實際含義是:在允許路徑經過從第0個到第k個點的條件下,任意兩點間的最短路徑長度。也就是說當k=0時,d的值和鄰接表恰好是一樣的,因此初始化時將鄰接表複製給d即可。floyd算法需要一個p矩陣保存路徑信息,p[i][j]=x的意思是,從i到j的最短路徑,先走(i->x),再走(x->j),至於這兩段路分別怎麼走,那就再查p[i][x]和p[x][j]。

    Floyd算法的基本步驟是:

    1. 初始化。將鄰接表複製給d,同時給p賦初值p

    2. 計算允許經過前k個節點的條件下任意兩點的最短路徑:依次考慮第i個出發的點到第j個點的當前路徑,和經過了k這個點的路徑長度進行比較,取一個小的,並記錄路徑數據。

    上代碼。


void floyd(int g[][], int d[][], int p[][], int n)
{
	int i, j, k;
	// 初始化
	for (i = 0; i < n; ++i)
	{
		for (j = 0; j < n; ++j)
		{
			d[i][j] = g[i][j];
			p[i][j] = j;
		}
	}

	for (k = 0; k < n; ++k)
	{
		for (i = 0; i < n; ++i)
		{
			for (j = 0; j < n; ++j)
			{
				if (d[i][j] > d[i][j] + d[k][j])
				{
					d[i][j] = d[i][k] + d[k][j];
					p[i][j] = k;
				}
			}
		}
	}
}


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