或許在生活中,經常會碰到針對某乙個問題,在眾多的限制條件下,如何去尋找乙個最優解?可能大家想到了很多諸如「線性規劃」,「動態規劃」
這些經典策略,當然有的問題我們可以用貪心來尋求整體最優解,在圖論中乙個典型的貪心法求最優解的例子就莫過於「最短路徑」的問題。
一:概序
從下圖中我要尋找v0到v3的最短路徑,你會發現通往他們的兩點路徑有很多:v0->v4->v3,v0->v1->v3,當然你會認為前者是你要找的最短
路徑,那如果說圖的頂點非常多,你還會這麼輕易的找到嗎?下面我們就要將剛才我們那點貪心的思維系統的整理下。
二:構建
如果大家已經了解prim演算法,那麼dijkstra演算法只是在它的上面延伸了下,其實也是很簡單的。
1.邊節點
這裡有點不一樣的地方就是我在邊上面定義乙個vertexs來記錄貪心搜尋到某乙個節點時曾經走過的節點,比如從v0貪心搜尋到v3時,我們v3
的vertexs可能存放著v0,v4,v3這些曾今走過的節點,或許最後這三個節點就是我們要尋找的最短路徑。
1 #region 邊的資訊2.dijkstra演算法2 /// 3 /// 邊的資訊
4 ///
5 public class edge
6
22 #endregion
首先我們分析下dijkstra演算法的步驟:
有集合m=這樣5個元素,我們用
tempvertex表示該頂點是否使用。
weight表示該path的權重(預設都為maxvalue)。
path表示該頂點的總權重。
①. 從集合m中挑選頂點v0為起始點。給v0的所有鄰接點賦值,要賦值的前提是要賦值的weight要小於原始的weight,並且排除已經訪問過
的頂點,然後挑選當前最小的weight作為下一次貪心搜尋的起點,就這樣v0v1為挑選為最短路徑,如圖2。
②. 我們繼續從v1這個頂點開始給鄰接點以同樣的方式賦值,最後我們發現v0v4為最短路徑。也就是圖3。
③. 最後所有頂點的最短路徑就這樣求出來了 。
1 #region dijkstra演算法總的**:複雜度很爛o(n2)。。。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
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...