Floyd和Dijkstra算法是一种在具有正或负边缘权重(但没有负周期)的加权图中找到最短路径的算法,不同点在于Floyd算法求加权图中所有顶点之间的最短路径; Dijkstra算法在求一点到其他所有顶点的最短路径
依次求距离源点的最短路径,再求还不确定的最小权值时(再求还未确定的顶点),就是从最后确定的最新权值的基础上(从那个顶点出发)遍历与他相连的边,在所有还未确定的顶点中找出最小的权值,即是确定下新的最短路径(最新顶点)
1.假设从D点开始,D为起始点,Visited[D] = 0 遍历与D相连的所有点,发现E最短,但D到BCF的距离也保留下来,保存在一个Visited数组里,E保存在S集合中,表示确定下来的顶点.
2.因为E与D距离最近,第二点从E开始,遍历E,CE为4,EF为5,所以计算D到F距离为6,比3大,所以保留3(如果新计算的权值大于原有的距离,保留新的权值),同理保留DF的3,ED的2因为visited[D] 已经确定下来 ,也因为 visited[D] = 0, visited[E] + 2 肯定>0 ,所以2无效的, S集合确定下来的顶点不用去遍历了,当然遍历了也没有关系,只是增加了运算的时间
3.确定了DC最近,下一个顶点就从C点出发,遍历C的所有顶点
我们是从原先顶点遍历中找出最短的权值,再与之前的还没确定下来的距离相比,找出最短的距离,确定最新的顶点
在无向图中,Dijkstra算法和图的层序遍历,BFS类似.但也不是BFS.
递归地进行n次更新, 每次确定同方向的相连的三个顶点,如果原先最远的两个顶点之间无边相连或者有边相连且权值大于相连的三顶点的权值相加,最远的两个顶点之间的距离被重新赋值为新的两权值相加的那个权值(如果小于,就保留原先的权值),再此基础上,进行新一轮的三顶点的比较,前一轮的三个顶点相加的权值为看作新一轮的其中的一个权值(如果原先小于的话,就用原先的最远距离的权值,第三个顶点不用加入)
比如原先AB权值6,但ACB权值相加为5,那么AB间的权值就为5,再计算AD的距离时,就用ACBD,权值相加为10,
k就表示迭代的次数,每次迭代只比较确定三个顶点,,下一次迭代,在此基础上再多一个顶点,将原来的基础看作一条权值,两个顶点,然后关联更多顶点,
path递归调用,每三个顶点比较确定相连的边,如果第三顶点加入,path指向第三顶点,如果不加入,就指向两顶点的后一顶底,再次基础上,新指向的顶点就是之前指向的那个顶点指向的顶点(就是跟起始点最近相连的顶点),输出时,就可以一层一层在返回指出这条路径,Floyd算法最好使用邻接矩阵
Dijkstra算法可以用反证法证明, 假设有两点之间的距离不是最短的,因为我们是从原先顶点遍历中找出最短的再与之前的还没确定下来的距离相比,找出最短的距离, 所以原先的顶点有比找出的顶点权值更小的权值,这明显违背, 第二种情况, 我们简单化,最新确定的距离AD 为10 有AC为3 CD 为7 ,当出现了更短的情况,如有AE为4,ED为5, 因为AE比AD短, 所以E点肯定比D点更早确定,E点确定时,肯定遍历了E点,AD为9的情况也早已确定,我们找出最短的权值后 相加 与之前的还没确定下来的距离也进行过比较,在确定最短,所以这种情况也违背,所以Dijkstra算法是正确的
Floyd算法 我只能感觉他是对的,,但很难证明,在这里分享一篇大佬写的比较好的,我也能看懂的
https://www.jianshu.com/p/21c9d60e7a03【图论】Floyd算法的证明
写的不好,还请包含
分享我写的代码:https://github.com/zhangweifeng66/algorithms