C++用Dijkstra(迪傑斯特拉)求最短路徑的演算法解析

來源:互聯網
上載者:User

演算法介紹

迪傑斯特拉演算法是由荷蘭電腦科學家狄克斯特拉於1959  年提出的,因此又叫狄克斯特拉演算法。是從一個頂點到其餘各頂點的最短路徑演算法,解決的是有向圖中最短路徑問題。迪傑斯特拉演算法主要特點是以起始點為中心向外層層擴充,直到擴充到終點為止。Dijkstra演算法能得出最短路徑的最優解,但由於它遍曆計算的節點很多,所以效率低。

演算法思想

按路徑長度遞增次序產生演算法:

 把頂點集合V分成兩組:

  (1)S:已求出的頂點的集合(初始時只含有源點V0)

  (2)V-S=T:尚未確定的頂點集合
  將T中頂點按遞增的次序加入到S中,保證:

  (1)從源點V0到S中其他各頂點的長度都不大於從V0到T中任何頂點的最短路徑長度

  (2)每個頂點對應一個距離值

  S中頂點:從V0到此頂點的長度

  T中頂點:從V0到此頂點的只包括S中頂點作中間頂點的最短路徑長度

  依據:可以證明V0到T中頂點Vk的,或是從V0到Vk的直接路徑的權值;或是從V0經S中頂點到Vk的路徑權值之和

應用舉例

(1)題目:編寫一個校園導遊程式,為來訪的客人提供各種資訊查詢服務。

    主要功能:1.設計學校的校園平面圖,所含景點不少於10個:頂點表示景點,邊表示路徑等;

         2.為客人提供圖中任意景點相關資訊的查詢;

         3.為客人提供圖中任意景點的問路查詢,即查詢人以景點間的一條最短路徑。

      要求:1.設計一個主介面;

              2.設計功能菜單,供使用者選擇

              3.有一定的實用性。

(2)設計思路:

  1、該題主要有演算法思路以及程式的邏輯思路,首先從邏輯思路講,進入程式,首先設計一個主菜單,選項有景點資訊查詢,最短路徑查詢以及顯示景點的平面視圖三個子功能表,然後根據使用者的輸入選擇的子功能表前的編號,分進入不同的子功能表;該功能是由if….else  if…. 語句實現。在景點資訊查詢和最短路徑查詢子功能表下還有二級子菜 單,都是列  出所有景點並在前面編號,查詢景點資訊時,輸入景點前面的編號即可,查詢最短路徑時,先輸入起點的編號,再輸入終點的編號。而顯示景點視圖則調用景點平面圖函數即可顯  示。

  2、演算法思路主要是迪傑斯特拉演算法的思路,利用迪傑斯特拉演算法求最短路徑。

  3、先定義好圖的儲存結構,本題採用鄰接矩陣的方式來表示圖,並在主函數中初始化該圖;

  4、定義三個全域一維數組,一個bool類型數組S[]用來記錄從v0到vi是否已經確定了最短路徑,是則記S[i]=true,否記S[i]= flase;一個int 類型數組Path[]用來記錄從v0到vi的當前最短路徑上的vi的直接前驅頂點編號,若v 到vi之間有邊則記Path[i] = v的編號,否則記Path[i] = -1;最後一個數組D[]用來記錄從v0到vi之間的最短路徑長度,存在則記v0到vi之間邊的權值或者權值和,否則記為MAX

  5、定義一個求最短路徑的函數,傳入的參數為圖和起點,首先進行初始化工作,初始化S[]數組全為false,D[]數組初始化為起點到各個頂點的權值,Path[]數組初始化為起點是否與各頂點有邊,有則記v0否則記-1;

  6、然後進行n-1次for迴圈,找出vo到其餘n-1個頂點之間的最短路徑,比較當前D[]數組中最小值,找到最小值的編號v,該編號就是從v0出發到所有頂點中距離最短的頂點編號,然後把S[v]的值置為true。說明從v0出發到頂點v已經找到最短路徑;

  7、接著就要更新D[]數組,因為D[]數組是記錄最短路徑的,現在已經找到了一個頂點的最短路徑,已該頂點v為中間點,判斷從該頂點v出發到剩下的頂點的路徑長度加上該點到v0的路徑長度是否小於直接從v0出發到其餘頂點的路徑長度,如果小於,則更新D[i]為以該頂點v為中間點求得的路徑長度。更新Path[i] = v;即i的前驅不再是v0而是v;

  8、迴圈(6)(7)兩步n-1次即可得到D[]數組,輸出D[]數組既是v0到所有頂點的最短路徑長度;

(3)原始碼:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

#include

#include

#include

usingnamespacestd;

/**

 *作者:Dmego

 *時間:2016-12-12

 */

#define MAX 1000000 //表示極大值∞

#define max 10

boolS[max];//記錄從源點V0到終點Vi是否已經確定為最短路徑,確定了記true,否則記false

intPath[max];//記錄從源點V0到終點Vi的當前最短路徑上終點Vi的直接前驅頂點序號,若V0到Vi之間有邊前驅為V0否則為-1

intD[max];//記錄源點到終點之間最短路徑的長度,存在記V0到Vi的邊的權值,否則記為MAX

typedefstruct

{

 string vexs[max];//頂點表

 intarcs[max][max];//鄰接矩陣

 intvexnum, arcnum;//圖當前點數和邊數

 

}AMGraph;

//利用迪傑斯特拉演算法求最短路徑

voidShortestPath_DIJ(AMGraph &G,intv0)

{//使用迪傑斯特拉演算法求有向網G中的V0 定點到其餘頂點的最短路徑

 intn = G.vexnum;//頂點數

 for(intv = 0; v < n; v++)//n個頂點依次初始化

 {

 S[v] =false;//S初始化為空白集

 D[v] = G.arcs[v0][v];//將v0到各個終點的最短路徑長度初始化為邊上的權值

 if(D[v] < MAX)

  Path[v] = v0;//如果v0和v之間有邊,則將v的前驅初始化為v0

 else

  Path[v] = -1;//如果v0和v之間無邊,則將v的前驅初始化為-1

 }

 S[v0] =true;//將v0加入s

 D[v0] = 0;//源點到源點的權值為0

 //---------初始化結束,開始主迴圈,每次求得v0到某個頂點的最短路徑,將v加到S數組

 for(inti = 1; i < n; i++)//依次對其餘n-1個頂點進行計算

 {

 intmin = MAX;

 intv = v0;

 for(intw = 0; w < n; w++)

 {

  if(!S[w] && D[w] < min)

  {//選擇一條當前最短路徑,終點為v

  v = w;

  min = D[w];

  }

  S[v] =true;//將v加到s集合中

  for(intw = 0; w < n; w++)

  {//更新從v0出發到集合V-S上所有頂點的最短路徑長度

  if(!S[w] && (D[v] + G.arcs[v][w] < D[w]))

  {

   D[w] = D[v] + G.arcs[v][w];//更新D[w]

   Path[w] = v;//更改w的前驅為v

  }

  }

 }

 }

}

//背景函數

voidbackGround()

{

 cout <<"|*****************************************************************| 100="" 125="" 135="" 140="" 145="" 150="" 160="" 200="" 230="" cout="" ------="">>>請選擇:";

}

//景點資訊查詢二級菜單

voidjmenu()

{

 cout <<"|*****************************************************************| cout="">>>請要查詢的景點編號:";

}

//最短路徑查詢二級菜單

voidpmenu()

{

 cout <<"|*****************************************************************| cout="">>>請依次輸入起點編號和終點編號:";

}

voidmain()

{

 //初始化操作

 AMGraph amg = { {"資訊學院","綜合餐廳","西操場","體育館","春暉樓",

   "基教","九教","九棟","沁園","翠園"},

 //-1代表兩邊不相連,權值無限大

 //鄰接矩陣 /* 信 綜 西 體 春 基 教 棟 沁 翠*/

   {{MAX,MAX,MAX,140,MAX,200,150,MAX,100,125 },

   {MAX,MAX,MAX,MAX,145,230,MAX,100,MAX,MAX },

   {MAX,MAX,MAX,150,MAX,MAX,200,MAX,MAX,MAX },

   {140,MAX,150,MAX,MAX,MAX,MAX,MAX,100,MAX },

   {MAX,145,MAX,MAX,MAX,150,MAX,MAX,MAX,MAX },

   {200,230,MAX,MAX,150,MAX,MAX,160,MAX,135 },

   {150,MAX,200,MAX,MAX,MAX,MAX,MAX,MAX,MAX },

   {MAX,200,MAX,MAX,MAX,160,MAX,MAX,MAX,MAX },

   {100,MAX,MAX,100,MAX,MAX,MAX,MAX,MAX,MAX },

   {125,MAX,MAX,MAX,MAX,135,MAX,MAX,MAX,MAX }

   },10,14};

 intf, ff;

 intstart, end;

 while(true)

 {

 cout << endl;

 menu();

 cin >> f;

 if(f == 1)

 {

  jmenu();

  cin >> ff;

       //景點資訊從檔案中讀取

  ifstream outfile("schooltravel.txt", ios :: out | ios :: binary);

  if(!outfile)

  {

  cerr <<"讀取景點介紹檔案失敗! string="" inti="m-1;" cout="" ff="=" f="=" cin="" start="" -="" inttemp="end-1;</div" m="0;</div" end="" temp1="temp" temp2="Path[temp1];</div" temp="temp2;</div" i="">";

  }

  cout << endl;

  cout <<"最短路徑值為: end="" -="" f="=" cout="">>>退出成功!"<< endl;

  exit(0);

 }

 }

}

(4)運行截圖:

總結

以上就是關於C++用Dijkstra演算法(迪傑斯特拉演算法)求最短路徑的全部內容了,希望本文的內容對大家的學習或者工作帶來一定的協助,如果有疑問大家可以留言交流。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.