当前位置:   article > 正文

数据结构(12)Dijkstra算法JAVA版:图的最短路径问题_dijkstra 最短路径本身 java

dijkstra 最短路径本身 java

目录

12.1.概述

12.1.1.无权图的最短路径

 12.1.2.带权图的最短路径

1.单源最短路径

2.多源最短路径

12.2.代码实现


12.1.概述

12.1.1.无权图的最短路径

无权图的最短路径,即最少步数,使用BFS+贪心算法来求解最短路径,比较好实现,此处不做展开讨论。

 12.1.2.带权图的最短路径

有权图的最短路径,不考虑权重为负数的情况,因为权重为负数的情况极有可能出现负值圈,在这个圈子上形成环路,最短路径是无限兜圈,趋于负无穷。

所以此处我们只考虑权重不为负数的带权图的最短路径求解问题。带权图的最短路径求解问题主要求两种最短路径:

  • 单源最短路径,某个点到全图各点之间的最短路径。
  • 多源最短路径,遍历全图的最短路径。

单源最短路径用Dijkstra算法求解,多源最短路径用Floyd算法求解。

1.单源最短路径

单源最短路径用Dijkstra算法求解,Dijkstra算法其本质是个贪心算法。整个过程就是选择局部最优解,组成最后的解。

以下展示一个Dijkstra求解v1的单源最短路径的过程:

 记录两个值:

distance,到某个结点的最短距离,初始化值为无穷大,表示暂时未记录。

route,全局最短路径,初始化值为-1,表示暂时未记录。

下标1234567
distance无穷大无穷大无穷大无穷大无穷大无穷大无穷大
route-1-1-1-1-1-1-1

 v1开始,刷新distance和route的值:

v1—>v1,distance为0

v1—>v2,distance为2<∞,将2刷新为v1—>v2的最短距离,将1(指代v1)刷新为最短路径。

v4同理……

下标1234567
distance02无穷大1无穷大无穷大无穷大
route-11-11-1-1-1

扫描distance表发现distance最小的v4,于是将v4上得到的数据刷新进distance和route:

下标1234567
distance0231395
route-1141444

一直重复上面步骤,直到图里所有结点都被遍历一次,会得到如下结果:

下标1234567
distance0231365
route-1141474

distance记录的是v1到每个结点的最短路径,route里面记录的最大值是全局遍历一遍的最短路径。

2.多源最短路径

多源最短路径用floyd算法求解,多源最短路径不能只关注于当前最优解,还要关注全局最优解,求解此类问题一般使用动态规划,floyd算法就是个求解多源最短路径的经典动态规划算法。本文主要论述Dijkstra算法,floyd算法暂时不展开。

12.2.代码实现

以遍历如下无向图为例(为什么不遍历上面的例子喃?因为代码是很久前写的了。上面的例子是写文的时候新写的,偷个懒不想改代码了~嘿嘿):

  1. public class Dijkstra {
  2. static int[][] graph;
  3. static int[] dist;
  4. static int[] path=new int[7];
  5. static boolean[] isUsed=new boolean[7];
  6. static {
  7. graph=new int[][]{
  8. {0,1,4,3,0,0,0},
  9. {1,0,3,0,0,0,0},
  10. {4,3,0,2,1,5,0},
  11. {3,0,2,0,2,0,0},
  12. {0,0,1,2,0,0,0},
  13. {0,0,5,0,0,0,2},
  14. {0,0,0,0,0,2,0}
  15. };
  16. dist=new int[]{Integer.MAX_VALUE,Integer.MAX_VALUE,Integer.MAX_VALUE,Integer.MAX_VALUE,Integer.MAX_VALUE,Integer.MAX_VALUE,Integer.MAX_VALUE};
  17. }
  18. public static void dijkstra(){
  19. while(true){
  20. //判断节点是否已经全部纳入
  21. if(isOver()){
  22. break;
  23. }
  24. //寻找未纳入的dist最小节点
  25. int i=findMin();
  26. //设置为已遍历状态
  27. isUsed[i]=true;
  28. //遍历该节点邻接节点
  29. for (int j=0;j<graph[i].length;j++) {
  30. if(graph[i][j]!=0&&isUsed[j]==false){
  31. //更新dist、path
  32. flashDistAndPath(i,j);
  33. }
  34. }
  35. }
  36. }
  37. public static int findMin(){
  38. int min=Integer.MAX_VALUE;
  39. int index=-1;
  40. for(int i=0;i<dist.length;i++){
  41. if(min>dist[i]&&isUsed[i]==false){
  42. min=dist[i];
  43. index=i;
  44. }
  45. }
  46. return index;
  47. }
  48. //之前的dist值一定是之前该节点到根节点的最短路径开销
  49. public static void flashDistAndPath(int i,int j){
  50. if(isUsed[j]==false) {
  51. if (graph[i][j] + dist[i] < dist[j]) {
  52. dist[j] = graph[i][j] + dist[i];
  53. path[j] = j;
  54. }
  55. }
  56. }
  57. public static boolean isOver(){
  58. int trues=0;
  59. for (boolean isused:isUsed) {
  60. if(isused==true){
  61. trues++;
  62. }
  63. }
  64. if(trues==dist.length){
  65. return true;
  66. }
  67. return false;
  68. }
  69. public static void main(String[] args) {
  70. isUsed[0]=true;
  71. dist[1]=1;
  72. dist[2]=4;
  73. dist[3]=3;
  74. path[1]=0;
  75. path[2]=0;
  76. path[3]=0;
  77. dijkstra();
  78. for (int i=0;i<dist.length;i++){
  79. System.out.println(dist[i]);
  80. }
  81. }
  82. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/152143
推荐阅读
相关标签
  

闽ICP备14008679号