floyd算法

Floyd算法

走远了吗. 提交于 2020-01-19 15:18:48
Floyd算法的基本思想如下:从任意节点A到任意节点B的最短路径不外乎2种可能,1是直接从A到B,2是从A经过若干个节点X到B。所以,我们假设Dis(AB)为节点A到节点B的最短路径的距离,对于每一个节点X,我们检查Dis(AX) + Dis(XB) < Dis(AB)是否成立,如果成立,证明从A到X再到B的路径比A直接到B的路径短,我们便设置Dis(AB) = Dis(AX) + Dis(XB),这样一来,当我们遍历完所有节点X,Dis(AB)中记录的便是A到B的最短路径的距离。 很简单吧,代码看起来可能像下面这样: ? for ( int i = 0; i < 节点个数; ++i ) { for ( int j = 0; j < 节点个数; ++j ) { for ( int k = 0; k < 节点个数; ++k ) { if ( Dis[i][k] + Dis[k][j] < Dis[i][j] ) { // 找到更短路径 Dis[i][j] = Dis[i][k] + Dis[k][j]; } } } } 但是这里我们要注意循环的嵌套顺序,如果把检查所有节点X放在最内层,那么结果将是不正确的,为什么呢?因为这样便过早的把i到j的最短路径确定下来了,而当后面存在更短的路径时,已经不再会更新了。 让我们来看一个例子,看下图: 图中红色的数字代表边的权重

Floyd算法

混江龙づ霸主 提交于 2020-01-19 15:17:49
  Floyd算法的基本思想如下:从任意节点A到任意节点B的最短路径不外乎2种可能,1是直接从A到B,2是从A经过若干个节点X到B。所以,我们假设Dis(AB)为节点A到节点B的最短路径的距离,对于每一个节点X,我们检查Dis(AX) + Dis(XB) < Dis(AB)是否成立,如果成立,证明从A到X再到B的路径比A直接到B的路径短,我们便设置Dis(AB) = Dis(AX) + Dis(XB),这样一来,当我们遍历完所有节点X,Dis(AB)中记录的便是A到B的最短路径的距离。 代码如下: for ( int i = 0; i < 节点个数; ++i ) { for ( int j = 0; j < 节点个数; ++j ) { for ( int k = 0; k < 节点个数; ++k ) { if ( Dis[i][k] + Dis[k][j] < Dis[i][j] ) { // 找到更短路径 Dis[i][j] = Dis[i][k] + Dis[k][j]; } } } } 但是这里我们要注意循环的嵌套顺序,如果把检查所有节点X放在最内层,那么结果将是不正确的,为什么呢?因为这样便过早的把i到j的最短路径确定下来了,而当后面存在更短的路径时,已经不再会更新了。 让我们来看一个例子,看下图: 图中红色的数字代表边的权重。如果我们在最内层检查所有节点X,那么对于A-

floyd算法证明

て烟熏妆下的殇ゞ 提交于 2020-01-11 04:37:30
算法介绍 作用:求多源最短路径 核心思想:算法 扫描一遍 n 判断 (A[ i ][ n ]+A[ n ][ j ] ) < A[ i ][ j ] (即判断 i -> j,i点到j点的距离是否小于从n点中转的距离) 如果小则刷新,因此复杂度是n3次方 算法实现 网上有很多参考:https://juejin.im/post/5cc79c93f265da035b61a42e 算法证明 不存在最短路径的场景: 不存在最短路径:存在负权环,理论上可以无穷小(此算法无法解决)。不通,表现为无穷大,两点的最短路径一直会是无穷大,因为没有中间的存在(如果有则两点相通)。 存在最短路径的场景: 存在最短路径,ab之间存在一条或多条最短路径。将ab的路径展开得到最短路径 a c d e f g b(路径可以是多条,但长度是一致); 递归思想:则 c d e f g 一定有一个顶点x(任意一个顶点)是最后刷新,则如果a x 和 x b的最短路径长度已经得到,则ab的最短路径长度则会刷新 此算法就是对的;递归思想 将 ax 划分成a y(y任意一顶点代称) 与yx ,xb 划分为x y 和yb,最后递归的边界为 a i(i任意顶点代称,最短路径a i之间无任何节点),然而ai 因为是最短路径,所以a到i的距离就是最短距离。所以此算法正确。 递推思想:每出现一个顶点 则此顶点的左右都是最短路径

最短路径_Floyd算法(多源)

回眸只為那壹抹淺笑 提交于 2019-12-27 01:25:26
Floyd算法是一个经典的动态规划算法,它又被称为插点法。该算法名称以创始人之一、1978年图灵奖获得者、斯坦福大学计算机科学系教授罗伯特·弗洛伊德命名。Floyd算法是一种利用动态规划的思想寻找给定的加权图中多源点之间最短路径的算法,算法目标是寻找从点i到点j的最短路径。 从任意节点i到任意节点j的最短路径不外乎2种可能,1是直接从i到j,2是从i经过若干个节点k到j。所以,算法假设Dis(i,j)为节点u到节点v的最短路径的距离,对于每一个节点k,算法检查Dis(i,k) + Dis(k,j) < Dis(i,j)是否成立,如果成立,证明从i到k再到j的路径比i直接到j的路径短,便设置Dis(i,j) = Dis(i,k) + Dis(k,j),这样一来,当遍历完所有节点k,Dis(i,j)中记录的便是i到j的最短路径的距离。 Floyd算法内容 / /求每队顶点之间的最短路径 //实现这个目的,有2种方式: //1.利用每个顶点为源头,共调用n次Dijstra算法 //2.Floyd算法,上下方案都是o(n^3) //辅助结构 1.二维数组Path[i][j],记录前驱 // 2.二维数组D[i][j],记录最短路径长度 //具体步骤: //初始化:D[i][j]=G.ver[i][j],然后进行(n-1)次比较和更新 //1.在vi和vj之间加入顶点v0,比较(vi,vj

Floyd算法(针对河大版教材错误修改)

旧巷老猫 提交于 2019-12-13 06:45:42
教材上Floyd算法最后打印出来的结果有点小问题 一开始着重于路径 path数组进行调整,先是调用n次Dijkstra算法 得到路径path 然后尝试调整Floyd算法中path数组。 浏览了网上其他的Floyd算法后,觉得问题不是在path数组上,而是在路径打印问题上,然后对路径打印做了些调整。 因本人能力有限,调整后的程序 也可能会有些许问题,恳请读者批评指正。 测试图 与数据 详见课本 # include <stdio.h> # include <stdlib.h> # define MaxVerNum 10 # define Infinity 1000 typedef struct { char vertex [ MaxVerNum ] ; int edges [ MaxVerNum ] [ MaxVerNum ] ; int vertex_num ; int edge_num ; } MGraph ; void Create_MG ( MGraph * G ) { int i , j , k , weight ; printf ( "Please input the vertex_num and edge_num\n" ) ; scanf ( "%d %d" , & ( G -> vertex_num ) , & ( G -> edge_num ) ) ; for ( i

数学建模方法-Floyd算法

匿名 (未验证) 提交于 2019-12-03 00:41:02
一、引言   哈喽大家好,今天要给大家讲的是 Floyd 算法。在那之前,大家还记得我们上一章讲的内容吗,就是那个 Dijkstra 算法,用来解决从 A 点到 B 点的最短路径问题。我们还给出了 Matlab 代码。 Floyd 算法也是用来处理最短路径问题的。它的理念跟 Dijkstra 有点不一样,但是最终的结果是一样的。 Floyd 算法主要是用到了 动态规划 的思想。在这里博主不打算讲到很抽象很高深的东西(毕竟博主也不是专业的),仅仅通过比较通俗易懂的方式来给大家讲解这个算法的思想( 如果有问题大家帮忙指出来哈 )。本文的图片和思想,借用了 (图片画得好好,有谁知道是用什么软件画的吗,博主也想学一学)。本篇的主要思想来自那篇博文,因此会有很多类似的,但博主还是想以自己的理解来解释Floyd算法的理念。好了我们开始吧... 二、 Floyd 算法   首先,大家看上面的图,暑假,小哼准备去一些城市旅游。有些城市之间有公路,有些城市之间则没有。为了节省经费以及方便计划旅程,小哼希望在出发之前知道任意两个城市之前的最短路程。我们用 1-4 来表示 4 个地点,并用 箭头 和箭头上的 数字 来表示一个地点到另一个地点的距离(注意,有些路是单向的)。这样就得到下图   现在,我们希望能求解出任意两点的最短路径及其距离。   好了,为了求解这个问题,我们先用一个二维的数组 A

FLOYD算法

匿名 (未验证) 提交于 2019-12-03 00:30:01
输入: n*n维矩阵l[ 1...n , 1...n ],以便对于有向图G({[ 1 , ...n },E)中的边(i,j)的长度为l[i,j] 输出: 矩阵 D,使得D[i,j]等于i到j的距离 步骤 ( ( ( dist(k)[i][j]的含义:允许中间顶点的序号最大为k时从vi到vj的最短路径长度。 dist(n-1)[i][j]就是vi到vj的最短路径长度。 时间复杂度分析: FLOYD算法的时间复杂度为 O(n^3); 文章来源: FLOYD算法

最短路之Floyd算法 (转)

匿名 (未验证) 提交于 2019-12-03 00:22:01
1.介绍   floyd算法只有五行代码,代码简单,三个for循环就可以解决问题,所以它的时间复杂度为O(n^3),可以求多源最短路问题。 2.思想: 举个例子:已知下图,   如现在只允许经过1号顶点,求任意两点之间的最短路程,只需判断e[i][1]+e[1][j]是否比e[i][j]要小即可。e[i][j]表示的是从i号顶点到j号顶点之间的路程。e[i][1]+e[1][j]表示的是从i号顶点先到1号顶点,再从1号顶点到j号顶点的路程之和。其中i是1~n循环,j也是1~n循环,代码实现如下。 for (i= 1 ; i<=n; i++ ) { for (j= 1 ; j<=n; j++ ) { if ( e[i][j] > e[i][ 1 ]+e[ 1 ][j] ) e[i][j] = e[i][ 1 ]+e[ 1 ][j]; } }   接下来继续求在只允许经过1和2号两个顶点的情况下任意两点之间的最短路程。在只允许经过1号顶点时任意两点的最短路程的结果下,再判断如果经过2号顶点是否可以使得i号顶点到j号顶点之间的路程变得更短。即判断e[i][2]+e[2][j]是否比e[i][j]要小,代码实现为如下。 // 经过1号顶点 for (i= 1 ; i<=n; i++ ) for (j= 1 ; j<=n; j++ ) if (e[i][j] > e[i][ 1 ]+e[ 1

Floyd算法(全源最短路径)

匿名 (未验证) 提交于 2019-12-02 23:41:02
1. Floyd算法是用来解决全源最短路径的问题,即给定图G(V,E),求任意两点u,v之间的最短路径长度,算法的思想比较简单,如果存在顶点k,使得以k作为中间顶点时顶点i和顶点j的当前最短距离缩短,则将dis[i][j]更新为dis[i][k] + dis[k][j],由于存在三层循环所以时间复杂度是O(n ^ 3),n为顶点的数量 2. 需要注意的问题是最外层的k循环不能够放入到最里面,因为后面的有可能更新到某一个顶点的时候,前面的顶点i,j顶点已经访问过了,所以不能够再访问了导致有的结果是错误的,所以k循环要放到最外面 下面是有向有权图的例子: 3. 具体的代码如下: import java.util.Arrays; import java.util.Scanner; public class Floyd算法 { static int d[][]; static int n = 0; static int edges; public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.println("输入顶点的个数: "); n = sc.nextInt(); d = new int[n][n]; System.out.println("输入边的条数: ");

利用指針訪問二維數組實現floyd算法

痞子三分冷 提交于 2019-12-01 11:56:30
#include<stdio.h> //floyd算法实现 //定义一个无限大值,表示无法直接通过的两个点 #define INF 999 //初始化一个n*n的数组存储所要表示的图 #define N 3 int a [N][N] ; //creat函数,用于初始化数组 int* creat (){ for(int i = 0 ;i<N;i++){ for(int j = 0 ;j<N;j++){ if(i==j) a[i][j] = 0 ; else a[i][j] = INF ; } } int* p = NULL ; p = a[0]; return p ; } //填充矩阵(输入图数据) int * insert(int* p ){ for(int i = 0 ;i<N;i++){ for(int j = 0;j<N;j++){ if(i!=j){ printf("请输入第%d城市到第%d城市的距离\n",i+1,j+1); scanf("%d",(p+i*N+j)); } } } return p ; } //创建弗洛伊德算法(三个嵌套for循环) int* floyd(int* p ){ for(int k = 0;k<N;k++){ for(int i = 0; i<N ;i++){ for(int j = 0 ; j<N;j++) if(*(p+i*N+j)>*