欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Dijkstra算法的Java实现

程序员文章站 2022-04-23 16:54:26
对应的图: 图的结构Ref:https://wenku.baidu.com/view/9fdeaa3c2b160b4e767fcff7.html 小结: 最重要的是记住:在搜索过程中,若节点i对应的distance[i]发生改变,那么对其任意一个邻居节点j,对应的distance[j]都要重新计算, ......
  1 package main.java;
  2 
  3 import main.java.utils.graphutil;
  4 
  5 import java.util.arraydeque;
  6 import java.util.list;
  7 import java.util.queue;
  8 
  9 
 10 /**
 11  * @tme 2019/9/12 10:40
 12  * @author chenhaisheng
 13  * @email:ecjutsbs@foxmail.com
 14  */
 15 public class dijkstratest {
 16 
 17     //邻接矩阵的表示
 18     public final static double[][] graph_distance = graphutil.getdijkstragraph();
 19 
 20     //起点到某节点的临时最短距离
 21     public static double distance[] = new double[graph_distance.length];
 22 
 23     //某节点的前驱节点
 24     public static int pre[] = new int[graph_distance.length];
 25 
 26     static int originindex = 0, toindex = 4;
 27 
 28 
 29     public static void main(string[] args) {
 30 
 31         init();
 32         finddijkstrashortestpath();
 33     }
 34 
 35     /*
 36     **初始化distance[]   pre[]
 37      */
 38     public static void init() {
 39 
 40         for (int i = 0; i < distance.length; i++) {
 41             if (i == originindex) {
 42                 distance[i] = 0.0;
 43                 continue;
 44             }
 45             distance[i] = double.max_value;
 46         }
 47 
 48         for (int i = 0; i < pre.length; i++) {
 49             pre[i] = -1;
 50         }
 51     }
 52 
 53     public static void finddijkstrashortestpath() {
 54 
 55         //queue用于保存尚待搜索的节点
 56         queue<integer> queue = new arraydeque<>();
 57 
 58         //起始,将起始节点添加到queue
 59         queue.add(originindex);
 60 
 61         while (queue.size() != 0) {
 62 
 63             integer currentindex = queue.poll();
 64 
 65             //获取当前节点的out-edges
 66             list<integer> neighbours = getneighbours(currentindex);
 67 
 68             for (int i = 0; i < neighbours.size(); i++) {
 69 
 70                 //获取邻居节点的索引值
 71                 int neighbourindex = neighbours.get(i);
 72 
 73                 //若起点经当前节点到邻居节点的距离 比直接到邻居节点的距离还小
 74                 if (distance[currentindex] + getdistance(currentindex, neighbourindex) < distance[neighbourindex]) {
 75 
 76                     //更新起点到邻居节点的距离
 77                     distance[neighbourindex] = distance[currentindex] + getdistance(currentindex, neighbourindex);
 78 
 79                     //设置下一个节点的前驱节点为当前节点
 80                     pre[neighbourindex] = currentindex;
 81 
 82                     //由于distance[neighbourindex]已经改变,因此需要重新搜索neighbourindex
 83                     queue.add(neighbourindex);
 84                 }
 85             }
 86         }
 87 
 88         //输出从originindex到toindex的路径
 89         printpath(pre, originindex, toindex);
 90     }
 91 
 92 
 93     public static void printpath(int pre[], int from, int to) {
 94 
 95         //栈
 96         deque<integer> path = new arraydeque<>();
 97 
 98         path.push(to);
 99 
100         int preindex = pre[to];
101         while (preindex != from) {
102             path.push(preindex);
103             preindex = pre[preindex];
104         }
105 
106         path.push(from);
107 
108         while (!path.isempty()) {
109             system.out.print(path.poll() + (path.size() > 0 ? "------>" : " "));
110         }
111         system.out.println(" ");
112     }
113 
114 
115     //获取当前节点所有的out-edges
116     public static list getneighbours(int index) {
117 
118         list<integer> res = new arraylist();
119 
120         //距离不为double.max_value,代表与当前节点连通
121         for (int i = 0; i < graph_distance[index].length; i++) {
122             if (graph_distance[index][i] != double.max_value)
123                 res.add(i);
124         }
125         return res;
126     }
127 
128     public static double getdistance(int from, int to) {
129         return graph_distance[from][to];
130     }
131 }

 

 1 package main.java.utils;
 2 
 3 /**
 4  * @tme ${data} 19:10
 5  * @author chenhaisheng
 6  * @email:ecjutsbs@foxmail.com
 7  */
 8 public class graphutil<t> {
 9 
10     public static double[][] getdijkstragraph(){
11         double max=double.max_value;
12         double[][] graph={
13                 {max,5,max,7,15},
14                 {max,max,5,max,max},
15                 {max,max,max,max,1},
16                 {max,max,2,max,max},
17                 {max,max,max,max,max}
18         };
19         return  graph;
20     }
21 }

 

对应的图:

Dijkstra算法的Java实现

图的结构ref:

 

小结:

最重要的是记住:在搜索过程中,若节点i对应的distance[i]发生改变,那么对其任意一个邻居节点j,对应的distance[j]都要重新计算,继而引发连锁反应。

对某一个节点k,distance[k]通常会发生会多次改变。