在图论中,在寻路最短路径中除了Dijkstra
算法之外,还有Floyd
算法也是很是经典,然而两种算法仍是有区别
的,Floyd主要计算多源最短路径。java
在单源正权值最短路径,咱们会用Dijkstra算法来求最短路径,而且算法的思想很简单——贪心算法:每次肯定最短路径的一个点而后维护(更新)这个点周围点的距离加入预选队列,等待下一次的抛出肯定。可是虽然思想很简单,实现起来是很是复杂
的,咱们须要邻接矩阵(表)储存长度,须要优先队列(或者每次都比较)维护一个预选点的集合。还要用一个boolean数组标记是否已经肯定、还要---------算法
总之,Dijkstra
算法的思想上是很容易接受的,可是实现上实际上是很是麻烦的。可是单源最短路径没有更好的办法。复杂度也为O(n2)
数组
而在n节点多源最短路径中,若是从Dijkstra算法的角度上,只须要将Dijkstra封装,而后执行n次Dijkstra算法便可,复杂度为O(n3)
。可是这样感受很臃肿,代码量巨大,占用不少空间内存。有没有啥方法可以稍微变变口味呢?学习
答案是有的,这就是易写但稍须要理解的Floyd
算法。一个求多元最短路径算法。spa
先看看百度百科的定义吧:.net
Floyd算法又称为插点法,是一种利用动态规划的思想寻找给定的加权图中多源点之间最短路径的算法,与Dijkstra算法相似。该算法名称以创始人之1、1978年图灵奖得到者、斯坦福大学计算机科学系教授罗伯特·弗洛伊德命名。3d
简单的来讲,算法的主要思想是动态规划(dp),而求最短路径须要不断松弛
(熟悉spfa算法的可能熟悉松弛)。code
而算法的具体思想为:cdn
邻接矩阵dist
储存路径,同时最终状态表明点点的最短路径。若是没有直接相连的两点那么默认为一个很大的值(不要溢出)!而本身的长度为0.第1个到第n个
点依次加入图中。每一个点加入进行试探是否有路径长度被更改。其中第三步的状态转移方程为:blog
dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j])
其中dp[x][y]
的意思能够理解为x到y的最短路径。因此dp[i][k]
的意思能够理解为i到k的最短路径dp[k][j]
的意思能够理解为k到j的最短路径.我们图解一个案例:
1
,你们能够发现,因为1的加入,使得原本不连通的2,3
点对和2,4
点对变得联通,而且加入1后距离为当前最小。(能够很直观加入5以后2,4,更短可是还没加入)。为了更好的描述其实此时的直接联通点多了两条。(2,3)和(2,4).咱们在dp中无论这个结果是经过前面那些步骤来的,可是在这个状态,这两点的最短距离就算它!
1
其中也使得3,1,4
这样联通,可是 3,1,4
联通的话距离为9远远大于原本的(3,4)
为2,因此不进行更新。至于算法的模拟两部核心已经告诉你们了,你们能够自行模拟剩下的。
而对于程序而言,这个插入的过程至关简单。核心代码只有四行! 代码以下
public class floyd {
static int max = 66666;// 别Intege.max 两个相加越界为负
public static void main(String[] args) {
int dist[][] = {
{ 0, 2, 3, 6, max, max },
{ 2, 0, max, max,4, 6 },
{ 3, max, 0, 2, max, max },
{ 6, max, 2, 0, 1, 3 },
{ max, 4, max, 1, 0, max },
{ max, 6, max, 3, max, 0 } };// 地图
// 6个
for (int k = 0; k < 6; k++)// 加入滴k个节点
{
for (int i = 0; i < 6; i++)// 松弛I行
{
for (int j = 0; j < 6; j++)// 松弛i列
{
dist[i][j] = Math.min(dist[i][j], dist[i][k] + dist[k][j]);
}
}
}
// 输出
for (int i = 0; i < 6; i++) {
System.out.print("节点"+(i+1)+" 的最短路径");
for (int j = 0; j < 6; j++) {
System.out.print(dist[i][j]+" ");
}
System.out.println();
}
}
}
复制代码
结果为:
固然,在你学习的过程当中,能够在每加入一个节点插入完成后,打印邻接矩阵的结果,看看前两部和笔者的是否相同(有助于理解
),若是相同,则说明正确!
你可能还会有疑惑,那咱么就用一个局部性来演示一下,看其中AB最短距离变化状况祝你理解:
好啦,Floyd算法就介绍到这里,若是对你有帮助,请动动小手点个赞吧!蟹蟹。 但愿和各位共同进步!欢迎关注笔者公众号:bigsai
!