图的最短路径和拓扑排序
Posted xiaozhongfeixiang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了图的最短路径和拓扑排序相关的知识,希望对你有一定的参考价值。
图的最短路径
从某顶点出发,沿图的边到达另一顶点所经过的路径中,各边上权值之和最小的一条路径叫做最短路径
图的最短路径有许多重要的应用。
例如:上图中v0-v8有9个点,可以看做不同的地点,现在要规划出v0到其它某个点地点的最短路线规划
构建最短路径中比较常见的一种算法即为dijstra(迪杰斯特拉)算法
二、dijstra(迪杰斯特拉)算法
究竟什么是迪杰斯特拉算法?它是如何寻找图中顶点的最短路径呢?
这个算法的本质,是不断刷新起点与其他各个顶点之间的 “距离表”。
让我们来演示一下迪杰斯特拉的详细过程:
第1步,创建距离表。表中的Key是顶点名称,Value是从起点A到对应顶点的已知最短距离。但是,一开始我们并不知道A到其他顶点的最短距离是多少,Value默认是无限大:
第2步,遍历起点A,找到起点A的邻接顶点B和C。从A到B的距离是5,从A到C的距离是2。把这一信息刷新到距离表当中:
第3步,从距离表中找到从A出发距离最短的点,也就是顶点C。
第4步,遍历顶点C,找到顶点C的邻接顶点D和F(A已经遍历过,不需要考虑)。从C到D的距离是6,所以A到D的距离是2+6=8;从C到F的距离是8,所以从A到F的距离是2+8=10。把这一信息刷新到表中:
接下来重复第3步、第4步所做的操作:
第5步,也就是第3步的重复,从距离表中找到从A出发距离最短的点(C已经遍历过,不需要考虑),也就是顶点B。
第6步,也就是第4步的重复,遍历顶点B,找到顶点B的邻接顶点D和E(A已经遍历过,不需要考虑)。从B到D的距离是1,所以A到D的距离是5+1=6,小于距离表中的8;从B到E的距离是6,所以从A到E的距离是5+6=11。把这一信息刷新到表中:
(在第6步,A到D的距离从8刷新到6,可以看出距离表所发挥的作用。距离表通过迭代刷新,用新路径长度取代旧路径长度,最终可以得到从起点到其他顶点的最短距离)
第7步,从距离表中找到从A出发距离最短的点(B和C不用考虑),也就是顶点D。
第8步,遍历顶点D,找到顶点D的邻接顶点E和F。从D到E的距离是1,所以A到E的距离是6+1=7,小于距离表中的11;从D到F的距离是2,所以从A到F的距离是6+2=8,小于距离表中的10。把这一信息刷新到表中:
第9步,从距离表中找到从A出发距离最短的点,也就是顶点E。
第10步,遍历顶点E,找到顶点E的邻接顶点G。从E到G的距离是7,所以A到G的距离是7+7=14。把这一信息刷新到表中:
第11步,从距离表中找到从A出发距离最短的点,也就是顶点F。
第10步,遍历顶点F,找到顶点F的邻接顶点G。从F到G的距离是3,所以A到G的距离是8+3=11,小于距离表中的14。把这一信息刷新到表中:
就这样,除终点以外的全部顶点都已经遍历完毕,距离表中存储的是从起点A到所有顶点的最短距离。显然,从A到G的最短距离是11。(路径:A-B-D-F-G)
代码实现:
package cn.itcast.grape; import cn.itcast.treeandgrape.Graph; public class JavaDijstra { private final static int MAXVEX = 9;//顶点,以后不需要写死 private final static int MAXWEING = 65535;//(最大)权重 private int shortTablePath[] = new int[MAXVEX];//存储V0到某顶点最短路径的权值和 例:{0,1,5} /** * 获取一个图的最短路径 */ public void shortestPathDijstra(Graph graph) { int min;//最小值 int k = 0;//记录下标 boolean isgetPath[] = new boolean[MAXVEX];//是否已经拿到了V0到Vm的最短路径 for (int v = 0; v < graph.getVertexSize(); v++) {//遍历顶点数量 shortTablePath[v] = graph.getMatrix()[0][v];//获得V0这一行的权值数组 } shortTablePath[0] = 0;//V0到V0的距离是0, 拿到数据后,不必往回走 isgetPath[0] = true; for (int v = 1; v < graph.getVertexSize(); v++) {//横向 min = MAXWEING;//初始化 for (int w = 0; w < graph.getVertexSize(); w++) {//纵向,对找出来的顶点一个一个遍历 if (!isgetPath[w] && shortTablePath[w] < min) { k = w; min = shortTablePath[w]; } } isgetPath[k] = true; for (int j = 0; j < graph.getVertexSize(); j++) { if (!isgetPath[j] && (min + graph.getMatrix()[k][j] < shortTablePath[j])) { shortTablePath[j] = min + graph.getMatrix()[k][j]; } } } for (int i = 0; i < shortTablePath.length; i++) { System.out.println("V0到V" + i + "的最短路径为:" + shortTablePath[i] + " "); } } public static void main(String[] args) { Graph graph = new Graph(MAXVEX); graph.createGraph(); JavaDijstra dijstra = new JavaDijstra(); dijstra.shortestPathDijstra(graph); } }
以上是关于图的最短路径和拓扑排序的主要内容,如果未能解决你的问题,请参考以下文章