基本概念

image.png

image.png

步骤分析

【数据结构】最短路径算法Dijkstra - 图3

  • 图的输入 | | n1 | n2 | n3 | n4 | n5 | n6 | | —- | —- | —- | —- | —- | —- | —- | | n1 | 0 | 2 | 1 | 5 | inf | inf | | n2 | 2 | 0 | 2 | 3 | inf | inf | | n3 | 1 | 2 | 0 | 3 | 1 | inf | | n4 | 5 | 3 | 3 | 0 | 1 | 5 | | n5 | inf | inf | 1 | 1 | 0 | 2 | | n6 | inf | inf | inf | 5 | 2 | 0 |

  • 迭代过程

    • 定义如下记号

【数据结构】最短路径算法Dijkstra - 图4 | N’ | D(2),P(2) | D(3),P(3) | D(4),P(4) | D(5),P(5) | D(6),P(6) | | —- | —- | —- | —- | —- | —- | | 1 | [D(2) Vs D(1)+C(1,2)]
[2 = 0 + 2]
D(2),P(2) = 2,1 | [D(3) Vs D(1)+C(1,3)]
[1 = 0 + 1]
D(3),P(3) = 1,1(MIN) | [D(4) Vs D(1)+C(1,4)]
[5 = 0 + 5]
D(4),P(4) = 5,1 | [D(5) Vs D(1)+C(1,5)]
[inf = 0 + inf]
D(5),P(5) = inf | [D(6) Vs D(1)+C(1,6)]
[inf = 0 + inf]
D(6),P(6) = inf | | 1,3 | [D(2) Vs D(3)+C(3,2)]
[2 < 1 + 2]
D(2),P(2) = 保留2,1 | | [D(4) Vs D(3)+C(3,4)]
[5 > 1 + 3]
D(4),P(4) = 更新4,3 | [D(5) Vs D(3)+C(3,5)]
[inf < 1 + 1]
D(5),P(5) = 更新2,3(MIN) | [D(6) Vs D(3)+C(3,6)]
[inf = inf]
D(6),P(6) = inf | | 1,3,5 | [D(2) Vs D(5)+C(5,2)]
[2 < 2 + inf]
D(2),P(2) = 保留2,1(MIN) | | [D(4) Vs D(5)+C(5,4)]
[4 > 2 + 1]
D(4),P(4) = 更新3,5 | | [D(6) Vs D(5)+C(5,6)]
[inf > 2 + 2]
D(6),P(6) = 更新4,5 | | 1,3,5,2 | | | [D(4) Vs D(2)+C(2,4)]
[3 < 2 + 3]
D(4),P(4) = 保留3,5(MIN) | | [D(6) Vs D(2)+C(2,6)]
[4 < 2 + inf]
D(6),P(6) = 保留4,5 | | 1,3,5,2,4 | | | | | [D(6) Vs D(4)+C(4,6)]
[4 < 3 + 5]
D(6),P(6) = 保留4,5(MIN) | | 1,3,5,2,4,6 | | | | | |

C++实现

  1. /*
  2. * Copyright (c) 2020 - ~, Wang Xi
  3. *
  4. * DIJKSTRA ALGORITHM
  5. * Used in C++
  6. *
  7. * Change Logs:
  8. * Date Author Notes Mail
  9. * 2021-04-17 WangXi first version WangXi_chn@foxmail.com
  10. */
  11. #include <iostream>
  12. #include <string>
  13. using namespace std;
  14. // Record the calculate result and be used in iteration
  15. struct Result
  16. {
  17. string path;
  18. int value;
  19. bool visit;
  20. };
  21. class Graph
  22. {
  23. public:
  24. int _inf_ = 10000;
  25. int vexnum = 6;
  26. int soucenode = 1;
  27. int arc[6][6] = {
  28. {0, 2, 1, 5, _inf_, _inf_},
  29. {2, 0, 2, 3, _inf_, _inf_},
  30. {1, 2, 0, 3, 1, _inf_},
  31. {5, 3, 3, 0, 1, 5},
  32. {_inf_, _inf_, 1, 1, 0, 2},
  33. {_inf_, _inf_, _inf_, 5, 2, 0}
  34. };;
  35. Result result[6];
  36. Graph(void);
  37. void GraphInit();
  38. string GraphPrint();
  39. string PathPrint();
  40. void Dijkstra();
  41. };
  42. Graph::Graph(void)
  43. {
  44. this->GraphInit();
  45. cout << this->GraphPrint() << endl;
  46. this->Dijkstra();
  47. cout << this->PathPrint() << endl;
  48. }
  49. void Graph::GraphInit() {
  50. for (int i = 0; i < this->vexnum; i++)
  51. {
  52. this->result[i].path = "";
  53. this->result[i].value = 0;
  54. this->result[i].visit = false;
  55. }
  56. }
  57. string Graph::GraphPrint()
  58. {
  59. string result = "图的邻接矩阵为:\r\n";
  60. int count_row = 0;
  61. int count_col = 0;
  62. while (count_row != this->vexnum)
  63. {
  64. count_col = 0;
  65. while (count_col != this->vexnum)
  66. {
  67. if (arc[count_row][count_col] == this->_inf_)
  68. result = result + "∞" + "\t";
  69. else
  70. result = result + std::to_string(arc[count_row][count_col]) + "\t";
  71. ++count_col;
  72. }
  73. ++count_row;
  74. result += "\r\n";
  75. }
  76. result += "\r\n";
  77. return result;
  78. }
  79. string Graph::PathPrint()
  80. {
  81. string str;
  82. str = "以D" + std::to_string(this->soucenode) + "为起点的最短路径为:\r\n";
  83. for (int i = 0; i != this->vexnum; i++)
  84. {
  85. if (result[i].value != _inf_)
  86. str += result[i].path + "=" + std::to_string(result[i].value) + "\r\n";
  87. else
  88. {
  89. str += result[i].path + "是无最短路径的" + "\r\n";
  90. }
  91. }
  92. return str;
  93. }
  94. void Graph::Dijkstra()
  95. {
  96. /* Config result array */
  97. int i;
  98. for (i = 0; i < this->vexnum; i++)
  99. {
  100. /* Set up default path */
  101. this->result[i].path = "D" + std::to_string(this->soucenode) + "-->D" + std::to_string(i + 1);
  102. result[i].value = arc[this->soucenode - 1][i];
  103. }
  104. /* Set up start to start node value */
  105. result[this->soucenode - 1].value = 0;
  106. result[this->soucenode - 1].visit = true;
  107. int count = 1;
  108. /* Calculate the rest node */
  109. while (count != this->vexnum)
  110. {
  111. //temp: the index of node has min length
  112. //min: the min path's length value
  113. int temp = 0;
  114. int min = _inf_;
  115. for (i = 0; i < this->vexnum; i++)
  116. {
  117. if (!result[i].visit && result[i].value < min)
  118. {
  119. min = result[i].value;
  120. temp = i;
  121. }
  122. }
  123. /* Mark the node had been choosen */
  124. result[temp].visit = true;
  125. ++count;
  126. for (i = 0; i < this->vexnum; i++)
  127. {
  128. if (!result[i].visit && arc[temp][i] != _inf_ && (result[temp].value + arc[temp][i]) < result[i].value)
  129. {
  130. /* Find the better path, updata the result array */
  131. result[i].value = result[temp].value + arc[temp][i];
  132. result[i].path = result[temp].path + "-->D" + to_string(i + 1);
  133. }
  134. }
  135. }
  136. }
  137. int main()
  138. {
  139. Graph graph;
  140. return 0;
  141. }
  142. /************************ (C) COPYRIGHT 2021 WANGXI **************END OF FILE****/