目录
前言:
Dijkstra算法是经典的图论算法,用于求得某个固定起点到任意顶点的最短路径。下面介绍一下经典的Dijkstra算法的java实现过程,而后引出问题,改进算法解决我们提出的问题。
Dijkstra算法实现:
Dijkstra算法介绍:
1.算法目的:在给出顶点集和邻接矩阵的图G中求出固定起点的顶点到其余顶点的最短路径。在算法中,定义五个集:
| visited | 顶点访问集合,记录了某个顶点是否已经被访问过,访问过则返回1,没有访问过为0。集合的大小等于顶点集的个数 |
| dis | 距离集合,记录起点顶点各个顶点之间的最小距离,最后输出该集合。集合的大小等于顶点集的个数。起点顶点到自身的距离为0 |
| pre | 前驱节点记录集合,用于记录某个访问顶点的前驱节点,表示该顶点是通过某个前驱节点指向的,通过这个集合我们可以追溯路径,集合的大小等于顶点集的个数 |
| martex | 邻接矩阵。用于表示图,是一个二维数组 |
| vertex | 顶点集合。 |
2.具体实现步骤:
- 初始化三个集合。将dis集合中,将全部值置为无穷大,表示目前没有任何两个顶点可以连通,pre集合的所有值置为0,visited所有值置为0。
- 获得出发顶点V(i),将顶点V对应的visited(i)值置为1,pre(i)值置为0,从dis集合中取出dis(i)的值,(对于出发顶点而言,这个值肯定是0),从martex中获得出发顶点到其余顶点,(例如j顶点)的距离,如果dis(i)+martex(i)(j)<dis(j),那么将dis集合中对应的dis(j)的值置为dis(i)+martex(i)(j),然后依次移动j的位置到最后一个顶点。第一轮赋值完成。
- 在dis数组中查找到最小的一个值对应的顶点(例如k),将该顶点对应的visited集合中的值置为1,然后取出dis(k)的值,将未访问的节点在依次进行访问(例如h),取出martex(k)(h)的值,如果dis(k)+martex(k)(h)<dis(h),那么更新dis集合中dis(h)的值,更新pre集合中pre(h)的值为k,表示起点到h的距离是通过k节点连接的。
- 重复3步骤,直到visited集合中的所有值置为1停止。输出dis集合和pre集合。
3.读懂dis集合和pre集合。
举一个例子:有六个顶点的图,将邻接矩阵经过dijkstra算法计算后,得到输出的dis集合,pre集合如下:
| dis | [0,5,7,12,17,19] |
| pre | [1,1,2,3,4,5] |
例如我们要找到V1-V6的最短距离,从dis中的dis(6)=19即可得出。那么V1是怎么走到V6的呢? 我们可以看pre集合。
pre(6)=5,表示V6的前驱节点是V5,我们于是找到pre(5)=4,表示V5的前驱节点是V4,然后我们再找到pre(4)=3,表示V4是通过V3找到的。如此下去,我们发现pre(2)=1,也就是说V2是通过V1找到的。V1前面没有前驱节点了(这里=1就表示是它本身),我们将这个寻找的过程倒着回去,就得到答案:1-2-3-4-5-6 ,就是V1-V6的最短路径,最短的值是19.
如果没有看懂上面的算法实现流程也没关系,可以去看Dijkstra算法分析中的具体问题的实现步骤,这样会对算法有更好的了解。
Dijkstra算法Java实现:
基于上面提到的思路分析,将思路用代码实现如下:
1.构建图类:
class Graph{
private String[] vertex;//顶点数组
private int[][] matrix;//邻接矩阵
private VisitedVertex vv;//实现Dijkstra算法时的存放数据的类。
public Graph(String[] vertex,int[][] matrix){
this.vertex=vertex;
this.matrix=matrix;
}
/**
* @param index 从哪个顶点开始(起点)
*
* */
public void dsj(int index){
vv= new VisitedVertex(vertex.length,index);
update(index);//更新index顶点到周围顶点的距离
for (int j=1;j<vertex.length;j++){
index=vv.updateArr();//返回新的访问顶点
update(index);
}
vv.show();
}
//更新index下标顶点到周围顶点的距离和周围顶点的前驱节点
public void update(int index){
int len=0;
for(int j=0;j<matrix[index].length;j++){
//len是出发顶点到index顶点的距离+从index顶点到j顶点的距离的和
len=vv.getDis(index)+matrix[index][j];
//如果j顶点没有被访问过,并且len小于出发顶点到j顶点的距离,就需要更新
if(!vv.in(j)&&len<vv.getDis(j)){
vv.updatePre(j,index);
vv.updateDis(j,len);
}
}
}
}
2.构建VisitedVertex类:
class VisitedVertex{
public int[] already_arr;//已经访问过的顶点集合
public int[] pre_visited;//顶点的前驱节点
public int[] dis;//距离记录数组
/**
*
* @param length 顶点的个数
* @param index 访问的起点
*/
public VisitedVertex(int length,int index){
this.already_arr=new int[length];
this.pre_visited=new int[length];
this.dis=new int[length];
Arrays.fill(dis,Short.MAX_VALUE);
this.already_arr[index]=1;
this.dis[index]=0;
}
/**
*
* @param index 判断顶点是否被访问过
* @return 访问过就返回true
*/
public boolean in(int index){
return already_arr[index]==1;
}
/**
* 更新出发顶点到index顶点的距离
* @param index index顶点
* @param len 出发点到该顶点的距离
*/
public void updateDis(int index,int len){
dis[index]=len;
}

本文介绍了Dijkstra算法的基本思想,详细展示了算法的Java实现过程,并通过一个设备更新问题来具体分析算法的应用。文章还讨论了算法的验证、可能存在的问题以及使用HashMap改进算法的方法。
最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



