經典演算法17 Dijkstra演算法

2021-08-14 20:27:23 字數 4154 閱讀 5147

或許在生活中,經常會碰到針對某乙個問題,在眾多的限制條件下,如何去尋找乙個最優解?可能大家想到了很多諸如「線性規劃」,「動態規劃」

這些經典策略,當然有的問題我們可以用貪心來尋求整體最優解,在圖論中乙個典型的貪心法求最優解的例子就莫過於「最短路徑」的問題。

一:概序

從下圖中我要尋找v0到v3的最短路徑,你會發現通往他們的兩點路徑有很多:v0->v4->v3,v0->v1->v3,當然你會認為前者是你要找的最短

路徑,那如果說圖的頂點非常多,你還會這麼輕易的找到嗎?下面我們就要將剛才我們那點貪心的思維系統的整理下。

二:構建

如果大家已經了解prim演算法,那麼dijkstra演算法只是在它的上面延伸了下,其實也是很簡單的。

1.邊節點

這裡有點不一樣的地方就是我在邊上面定義乙個vertexs來記錄貪心搜尋到某乙個節點時曾經走過的節點,比如從v0貪心搜尋到v3時,我們v3

的vertexs可能存放著v0,v4,v3這些曾今走過的節點,或許最後這三個節點就是我們要尋找的最短路徑。

1 #region 邊的資訊

2 /// 3 /// 邊的資訊

4 ///

5 public class edge

6

22 #endregion

2.dijkstra演算法

首先我們分析下dijkstra演算法的步驟:

有集合m=這樣5個元素,我們用

tempvertex表示該頂點是否使用。

weight表示該path的權重(預設都為maxvalue)。

path表示該頂點的總權重。

①. 從集合m中挑選頂點v0為起始點。給v0的所有鄰接點賦值,要賦值的前提是要賦值的weight要小於原始的weight,並且排除已經訪問過

的頂點,然後挑選當前最小的weight作為下一次貪心搜尋的起點,就這樣v0v1為挑選為最短路徑,如圖2。

②. 我們繼續從v1這個頂點開始給鄰接點以同樣的方式賦值,最後我們發現v0v4為最短路徑。也就是圖3。

③. 最後所有頂點的最短路徑就這樣求出來了 。

1 #region dijkstra演算法

2 /// 3 /// dijkstra演算法

4 ///

5 public dictionarydijkstra()

6 );

17 }

18 19 //取第乙個頂點

20 var start = 0;

21 22 for (int i = 0; i < graph.vertexsnum; i++)

23 ;

49 50 //將上乙個邊的節點的vertex累加

51 dic_edges[end].vertexs = new hashset(dic_edges[start].vertexs);

52 53 dic_edges[end].vertexs.add(start);

54 dic_edges[end].vertexs.add(end);

55 }

56 }

57 }

58 59 var min = int.maxvalue;

60 61 //下乙個進行比較的頂點

62 int minkey = 0;

63 64 //取start鄰接邊中的最小值

65 foreach (var key in dic_edges.keys)

66

73 }

74 75 //從鄰接邊的頂點再開始找

76 start = minkey;

77 }

78 79 return dic_edges;

80 }

81 #endregion

總的**:複雜度很爛o(n2)。。。

using system;

using system.collections.generic;

using system.linq;

using system.text;

using system.diagnostics;

using system.threading;

using system.io;

using system.threading.tasks;

", string.join("->", result[key].vertexs));

}console.read();}}

#region 定義矩陣節點

/// /// 定義矩陣節點

///

public class matrixgraph

#region 矩陣的構建

/// /// 矩陣的構建

///

public void build()

}//定義 6 條邊

graph.edges[0, 1] = graph.edges[1, 0] = 2;

graph.edges[0, 2] = graph.edges[2, 0] = 5;

graph.edges[0, 4] = graph.edges[4, 0] = 3;

graph.edges[1, 3] = graph.edges[3, 1] = 4;

graph.edges[2, 4] = graph.edges[4, 2] = 5;

graph.edges[3, 4] = graph.edges[4, 3] = 2;

}#endregion

#region 邊的資訊

/// /// 邊的資訊

///

public class edge

#endregion

#region dijkstra演算法

/// /// dijkstra演算法

///

public dictionarydijkstra());}

//取第乙個頂點

var start = 0;

for (int i = 0; i < graph.vertexsnum; i++)

;//將上乙個邊的節點的vertex累加

dic_edges[end].vertexs = new hashset(dic_edges[start].vertexs);

dic_edges[end].vertexs.add(start);

dic_edges[end].vertexs.add(end);}}

}var min = int.maxvalue;

//下乙個進行比較的頂點

int minkey = 0;

//取start鄰接邊中的最小值

foreach (var key in dic_edges.keys)

}//從鄰接邊的頂點再開始找

最短路 Floyd演算法和Dijkstra演算法

兩者在負權問題上不是很好,最好只處理正值,dijkstra演算法對負權毫無辦法,但是floyd演算法不能處理出現負環的東西。dijkstra演算法的話,為了方便,我認為從i到i點不可達 百部百科解釋挺好,那個堆優化挺好的 floyd演算法百部百科也不錯,都是老演算法了,哪都有資料 這位筒子的寫得很好...

ACM之路 5 最短路演算法 Dijkstra演算法

簡介 dijkstra演算法是一種單源路徑演算法。時間複雜度為 o n 2 比floyd演算法 o n 3 快很多。當然,dijkstra演算法可以用堆優化後,演算法複雜度成了 o m n logn 複雜度更底了。本文只講解dijkstra的簡單演算法。問題 給予n個城市和m條道路,求從城市1到城市...

第十三周專案 驗證演算法之Dijkstra演算法

問題及 檔名稱 cube007.cpp 作 者 劉小楠 完成日期 2016年11月24日 問題描述 dijkstra演算法的驗證。輸入描述 無 輸出描述 結果 include include include graph.h define maxsize 100 void ppath int path...