Dijkstra 算法
来源:互联网 发布:kcf跟踪算法 编辑:程序博客网 时间:2024/04/25 13:54
Dijkstra 算法
Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。Dijkstra算法是很有代表性的最短路径算法,在很多专业课程中都作为基本内容有详细的介绍,如数据结构,图论,运筹学等等。注意该算法要求图中不存在负权边。
问题描述:在无向图 G=(V,E) 中,假设每条边 E[i] 的长度为 w[i],找到由顶点 V0 到其余各点的最短路径。(单源最短路径)
1)算法思想:设G=(V,E)是一个带权有向图,把图中顶点集合V分成两组,第一组为已求出最短路径的顶点集合(用S表示,初始时S中只有一个源点,以后每求得一条最短路径 , 就将加入到集合S中,直到全部顶点都加入到S中,算法就结束了),第二组为其余未确定最短路径的顶点集合(用U表示),按最短路径长度的递增次序依次把第二组的顶点加入S中。在加入的过程中,总保持从源点v到S中各顶点的最短路径长度不大于从源点v到U中任何顶点的最短路径长度。此外,每个顶点对应一个距离,S中的顶点的距离就是从v到此顶点的最短路径长度,U中的顶点的距离,是从v到此顶点只包括S中的顶点为中间顶点的当前最短路径长度。
1)算法思想:设G=(V,E)是一个带权有向图,把图中顶点集合V分成两组,第一组为已求出最短路径的顶点集合(用S表示,初始时S中只有一个源点,以后每求得一条最短路径 , 就将加入到集合S中,直到全部顶点都加入到S中,算法就结束了),第二组为其余未确定最短路径的顶点集合(用U表示),按最短路径长度的递增次序依次把第二组的顶点加入S中。在加入的过程中,总保持从源点v到S中各顶点的最短路径长度不大于从源点v到U中任何顶点的最短路径长度。此外,每个顶点对应一个距离,S中的顶点的距离就是从v到此顶点的最短路径长度,U中的顶点的距离,是从v到此顶点只包括S中的顶点为中间顶点的当前最短路径长度。
本算法的主要步骤:
1.找出距离起始顶点距离最短的顶点,这里设为顶点nowVertice.
2.遍历所有与顶点nowVertice相邻的顶点nextVertice.如果发现选择nowVertice到达nextVertice的路径后,nextVertice距离起始顶点的距离比当前的距离小.便更新新的距离.如下:
if(currDist[nextVertice] > currDist[nowVertice] + weight) { //weight为从nowVertice到nextVertice说需要的权重 currDist[nextVertice] = currDist[nowVertice] + weight; }
currDist是一个全局数组,currDist[i]意思就是当前起始顶点到顶点i的距离.
3.将nowVertice从图中删除.
4.重复步骤1,直到所有的顶点都被删除完.
补充,在实现的时候,上面说的删除并不是真的直接从图中把某一顶点删除,这里会使用一个集合来存储所有的顶点,对该集合中的顶点进行删除动作,集合如下.
List<Integer> toBeChecked = new LinkedList<>();
这里使用一个名为Graph的类来封装查找最短路径的相关内容:
/** * 使用邻接矩阵实现图<p> * 深度优先遍历与广度优先遍历<p> * 求最短路径:<p> * 1. Dijkstra 算法 <p> * 2. Ford 算法 <p> * 3. 通用型的纠正标记算法<p> * Created by Henvealf on 16-5-22. */public class Graph<T> { private int[][] racs; //邻接矩阵 private T[] verticeInfo; //各个点所携带的信息. private int verticeNum; //顶点的数目, private int[] visitedCount; //记录访问 private int[] currDist; //最短路径算法中用来记录每个顶点距离起始顶点路径的长度. public Graph(int[][] racs, T[] verticeInfo){ if(racs.length != racs[0].length){ throw new IllegalArgumentException("racs is not a adjacency matrix!"); } if(racs.length != verticeInfo.length ){ throw new IllegalArgumentException ("Argument of 2 verticeInfo's length is error!"); } this.racs = racs; this.verticeInfo = verticeInfo; verticeNum = racs.length; visitedCount = new int[verticeNum]; } //.......... }
这里是使用的邻接矩阵来表示图,想要使用其他表示方法,自行稍微修改一下便可.下面是实现方法的代码:
1 /** 2 * 使用 Dijkstra算法寻找最短路径 3 * @param first 路径开始的顶点 4 * @return 返回最后的最短路径 5 */ 6 public int[] dijkstraAlgorithm(int first){ 7 if(first < 0 || first >= verticeNum ){ 8 throw new IndexOutOfBoundsException ("should between 0 ~ " + (verticeNum -1)); 9 }10 setNumberAsInfinitie();11 currDist[first] = 0;12 List<Integer> toBeChecked = new LinkedList<>();13 for(int i = 0; i < verticeNum; i ++){14 toBeChecked.add(i);15 }16 while(!toBeChecked.isEmpty()){17 int nowVertice = findMinCurrDistVerticeAndRemoveFormList(toBeChecked);18 for(int i = 0; i < verticeNum; i ++){19 int nextVertice = -1; //邻接节点20 int weight = Integer.MAX_VALUE; //到达邻接节点的权重21 if(racs[nowVertice][i] != Integer.MAX_VALUE){ //得到邻接顶点22 if(toBeChecked.contains(i)){23 nextVertice = i;24 weight = racs[nowVertice][i];25 }26 }27 if(nextVertice == -1) {continue;}28 if(currDist[nextVertice] > currDist[nowVertice] + weight){29 currDist[nextVertice] = currDist[nowVertice] + weight;30 }31 }32 33 }34 for(int i = 0; i < currDist.length; i++){35 System.out.println("现在顶点 " + verticeInfo[i].toString() + " 距离顶点 " + verticeInfo[first].toString() + " 的最短距离为 " + currDist[i]);36 }37 return currDist;38 }39 /**40 * 将currDist数组初始化为无穷大41 */42 private void setNumberAsInfinitie(){43 currDist = new int[verticeNum];44 for (int i = 0; i < verticeNum; i++){45 currDist[i] = Integer.MAX_VALUE;46 }47 }48 49 /**50 * 寻找出当前距离起始顶点路径最短的顶点,并将其从toBeCheck中删除51 * @param list52 * @return53 */54 private int findMinCurrDistVerticeAndRemoveFormList(List<Integer> list){55 int num = list.get(0);56 int dist = currDist[list.get(0)];57 int listIndex = 0;58 for(int i = 1; i < list.size(); i ++){59 int index = list.get(i);60 if(currDist[index] < dist) {61 dist = currDist[index];62 num = index;63 listIndex = i;64 }65 }66 list.remove(listIndex);67 return num;68 }
0 0
- Dijkstra算法
- dijkstra算法
- Dijkstra算法
- Dijkstra算法
- Dijkstra算法
- Dijkstra算法
- Dijkstra 算法
- Dijkstra算法
- Dijkstra算法
- Dijkstra算法
- Dijkstra 算法
- Dijkstra 算法
- dijkstra算法
- Dijkstra 算法
- Dijkstra算法
- Dijkstra算法
- Dijkstra算法
- dijkstra算法
- ActivityManager、ActivityManagerService、ActivityManagerNative、ActivityManagerProxy的关系(and5.1)
- 笔记3:caffe训练现有的模型
- Java Script总结
- 字符串空格查找替换
- LeetCode 简单操作 | 7. Reverse Integer
- Dijkstra 算法
- 【关于HTTP协议】
- 网络黑白 作者花无涯亲身感悟“中国黑客”数十载变迁
- 为小伙伴加福利
- strlen和sizeof取字符串长度的区别
- 什么是分布式账本?
- 类似QQ聊天界面
- el表达式中==null 和empty
- Android6.0之指纹识别