最短路径算法--Floyd算法
Floyd算法(各对顶点之间的最短距离)

Floyd算法(各对顶点之间的最短距离)Floyd算法(各对顶点之间的最短距离)在上篇文章中议论到了如何求算单源最短路径,因此要想求各对顶点之间的距离,只需循环求算n次即可。
还有另外一种办法来求算各对顶点之间的最短距离,就是Floyd算法,因为其算法过程比Dijksa更简单理解,并且代码更简洁,因此当求算各对顶点之间的最短距离常采纳Floyd算法。
一.Floyd算法假设从i到j的最短路径上要经过若干个顶点,这些中间顶点中最大的顶点编号为k,最小的顶点为t,因此要求算dist[i][j]的最小值,那么只需要求算dist[i][s]+dist[s][j](t =s =k)的全部值,并取其中最小者即可。
因此可以设置一个中间顶点k(0 =k n)分离插入到每队顶点(i,j)之中,并更新dist[i][j]的值。
当n个顶点插入到每队顶点之中,求解便结束了。
其实Floyd算法实质上是一个动态规划算法。
代码实现: /*每对顶点之间最短路径Floyd 2011.8.27*/ iludeiostream include stack define M 100define N 100using namespace std;typef struct node{ int matrix[N][M]; //邻接矩阵 int n; //顶点数 int e; //边数 }MGraph; vo FloydPath(MGraph g,intdist[N][M],int path[N][M]){ int i,j,k; for(i=0;i g.n;i++)for(j=0;j g.n;j++) { if(g.matrix[i][j] 0){ dist[i][j]=g.matrix[i][j]; path[i][j]=i; } ee { if(i!=j) { dist[i][j]=INT_MAX; path[i][j]=-1; } else { dist[i][j]=0; path[i][j]=i; } } } for(k=0;k g.n;k++) //中间插入点(注重理解k为什么只能在最外层) for(i=0;i g.n;i++) for(j=0;jg.n;j++) { if((dist[i][k] 0 dist[i][k] INT_MAX) //防止加法溢出 (dist[k][j] 0 dist[k][j] INT_MAX) dist[i][k]+dist[k][j] dist[i][j]) { dist[i][j]=dist[i][k]+dist[k][j];path[i][j]=path[k][j]; //path[i][j]记录从i到j的最短路径上j 的前一个顶点 } } }void showPath(int path[N][M],int s,int t) //打印出最短路径 { stack int st; int v=t; while(t!=s) { st.push(t);第1页共2页。
最短路径——floyd算法代码(c语言)

最短路径——floyd算法代码(c语⾔)最短路径问题昨天⾃⼰试了试写⼀下dijkstra的算法博客今天来更floyd算法,感觉⾮常简单果然暴⼒才是解决⼀切的王道⼀、总体思想floyd算法就是每⼀次从邻接矩阵选取⼀个顶点k,然后再去矩阵中遍历两个顶点i,j,看看是i→j的路径短,还是i→k→j的路径短,就是完全的暴⼒,算法和代码⾮常简单⼆、代码实现1void Floyd(Graph G)2 {3int arr[G.vexnum][G.vexnum];4for(int i = 0; i < G.vexnum; i++)5for(int j = 0; j < G.vexnum; i++)6 arr[i][j] = G.edge[i][j];78for(int k; k < G.vexnum; k++)9for(int i = 0; i < G.vexnum; i++)10for(int j = 0; j < G.vexnum; j++)11if(arr[i][j] > arr[i][k] + arr[k][j])12 arr[i][j] = arr[i][k] + arr[k][j];13 }三、代码解释其实看上⾯的代码量和代码就知道这个算法很简单 =_=传⼊Floyd算法的参数是Graph G⾸先开辟⼀个⼆维数组arr[][],并且把图的邻接矩阵G.edge[][]赋值给arr[][],算法的主要思想就是来修改arr[][]值暴⼒出最短路径1int arr[G.vexnum][G.vexnum];//开辟数组arr[][]接收图G.edge[][]的值2for(int i = 0; i < G.vexnum; i++)3for(int j = 0; j < G.vexnum; i++)4 arr[i][j] = G.edge[i][j];//遍历赋值然后就是每次选择⼀个顶点k,再去找两个顶点i,j,对⽐看看是i→j的路径短,还是i→k→j的路径短也就是arr[i][j] 和 arr[i][k] + arr[k][j]两个的值谁的⽐较⼩,然后修改arr[][]⼀直到遍历完毕1for(int k; k < G.vexnum; k++)//选取k顶点2for(int i = 0; i < G.vexnum; i++)3for(int j = 0; j < G.vexnum; j++)//再选取i,j两个顶点4if(arr[i][j] > arr[i][k] + arr[k][j])//判断i→j的路径和i→k→j的路径谁⽐较短5 arr[i][j] = arr[i][k] + arr[k][j];//如果i→k→j的路径更短,则修改数组arr[][]写完感觉好短。
最短路径算法--Floyd算法

Floyd’s Algorithm 4
The subproblems
• Let D(k)[i,j]=weight of a shortest path from vi to vj using only vertices from {v1,v2,…,vk} as intermediate vertices in the path
Floyd's Algorithm: Using 2 D matrices
Floyd 1. D W // initialize D array to W [ ] 2. P 0 // initialize P array to [0] 3. for k 1 to n // Computing D’ from D 4. do for i 1 to n 5. do for j 1 to n 6. if (D[ i, j ] > D[ i, k ] + D[ k, j ] ) 7. then D’[ i, j ] D[ i, k ] + D[ k, j ] 8. P[ i, j ] k; 9. else D’[ i, j ] D[ i, j ] 10. Move D’ to D.
Floyd’s Algorithm 14
Can we use only one D matrix?
• D[i,j] depends only on elements in the kth column and row of the distance matrix. • We will show that the kth row and the kth column of the distance matrix are unchanged when Dk is computed • This means D can be calculated in-place
佛洛伊德算法

佛洛伊德算法
佛洛伊德算法(Floyd算法)是一种利用动态规划的思想寻找给定的加权图中多源点之间最短路径的算法,以创始人之一、1978年图灵奖获得者、斯坦福大学计算机科学系教授罗伯特·弗洛伊德命名。
该算法的基本思想是通过Floyd计算图G=(V,E)中各个顶点的最短路径时,需要引入一个矩阵S,矩阵S中的元素a[i][j]表示顶点i(第i个顶点)到顶点j(第j个顶点)的距离。
具体步骤如下:
1.初始化S。
矩阵S中顶点a[i][j]的距离为顶点i到顶点j的权值;如果i和j不相邻,则a[i][j]=∞。
实际上,就是将图的原始矩阵复制到S中。
2.以顶点A(第1个顶点)为中介点,若a[i][j]>a[i][0]+a[0][j],则设置a[i][j]=a[i][0]+a[0][j]。
请注意,在具体使用中,可能需要根据问题的具体情况对该算法进行适当的调整。
Floyd算法

Floyd算法Floyd算法是一种经典的图论算法,用于求解带权有向图中任意两个顶点之间的最短路径问题。
该算法由美国数学家罗伯特·弗洛伊德(Robert Floyd)于1962年提出,因此得名为Floyd算法。
Floyd算法是一种动态规划算法,它采用了“分治”的思想,将问题分解为更小的子问题,然后逐步解决子问题,最终得到解决整个问题的结果。
本文将从算法的背景、基本思想、实现方法及优缺点等方面对Floyd 算法进行详细阐述和分析。
一、算法的背景在讲Floyd算法之前,我们先来了解一下最短路径问题。
顾名思义,最短路径问题就是在给定图中找到两个给定节点之间的一条最短路径,也就是路径上各边权值之和最小的路径。
这个问题在现实生活中有很多应用,比如网络路由、地图路径规划、航线安排等等。
在数学和计算机科学领域中,我们可以通过图论的方法来描述和解决这个问题。
一般来说,给定一张带权有向图G=(V, E),其中V表示节点的集合,E表示边的集合。
每条边E(i,j)的权重为w(i,j),表示从节点i到节点j的距离或成本。
那么最短路径问题就是在图中找到从节点s到节点t的一条最短路径P,并且P上的边权之和最小。
最初求解的思路是按照类似深度优先搜索的方式,逐个遍历所有路径,然后依次比较它们的距离,找到最短路径。
但这种方式显然是不可行的,因为它的时间复杂度非常高。
所以,我们需要设计一种更高效的算法,以求得最短路径问题的最优解。
二、算法的基本思想Floyd算法就是一种高效地解决最短路径问题的方法。
它采用了“动态规划”的思想,通过逐步求解子问题,最终得到完整的最短路径。
而解决子问题的方式则是采用了“分治”的思想,将问题分解为更小的子问题,然后逐步解决。
具体地说,Floyd算法采用了“中转节点”的概念,我们可以将问题转化为这样一个子问题:对于每个节点i和节点j,假设我们已经知道了它们之间的最短路径长度为d[i][j],那么考虑一下节点k作为中转节点,它可以为i和j之间的路径P提供一个“中转服务”,将P拆分为两条路径:i-->k和k-->j。
简介Floyd算法

简介Floyd 算法⽬录1. 定义Floyd 算法是⼀种⽤于寻找给定的加权图中顶点间最短路径,是经典的多源最短路径算法,可以有效地处理有向图或负权的最短路径问题,同时也被⽤于计算有向图的传递闭包。
Floyd 算法的时间复杂度为 O (N 3),空间复杂度为 O (N 2)。
2. 优缺点优点:容易理解,可以算出任意两个节点之间的最短距离,代码编写简单。
缺点:时间复杂度⽐较⾼,不是和计算⼤量数据。
3. 基本思想Floyd 算法属于动态规划算法,即寻找节点 i 到节点 j 的最短路径。
Step 1: 初始距离定义 n 节点⽹络的邻接矩阵 A n ×n ,矩阵中的元素为 a i ,j 为节点 i 到节点 j 的⼀步的直线距离。
令 A (0)=A ,其初始元素为 a (0)i ,j 则该距离有如下三种情况:a (0)i ,j =c i ,j , i ,j 相连0, i =j∞, i ,j 不相连其中,节点 i , j 之间有直线连接时,则 a (0)i ,j 为其距离值 c i ,j ;节点 i 到⾃⾝的距离为 0;节点 i , j 之间没有直线连接时,则 a (0)i ,j 则为 ∞,如下图:则该初始邻接矩阵 A 为:即节点0与节点0⾃⾝距离值为0,即 A [0][0]=0;节点0与节点1之间有直线连接,距离值为5,即 A [0][1]=5;节点0与节点2之间没有直线连接,则距离值为 ∞,即 A [0][2]=∞;节点0与节点3之间有直线连接,距离值为7,即 A [0][3]=7 ……其他节点间的初始距离可依次写出,即为该邻接矩阵 A 。
Step 2: 借中转节点迭代找最短路径节点 i , j 间⼀步达不到时,则需要在两节点之间通过其他节点(如节点 k )作连接:在 A 矩阵上做 n 次迭代,k =1,⋯,n ,第 k 次迭代a k i ,j =min (a k −1i ,j ,a k −1i ,k +a k −1k ,j )即在节点 i 和节点 j 之间找到⼀条最短距离的路径,如下图:图中的节点 i 到节点 j 之间的直线距离 (i →j ) 为 6,但经过节点 k 作中转后,节点 i 到节点 j 之间的直线距离 (i →k →j ) 为 2+3=5,因此 a k i ,j =min (6,5)=5。
点到点的最短路径算法

点到点的最短路径算法
点到点的最短路径算法在计算机科学中是一个非常常见的问题,其主要用于在图中找到从一个点到另一个点的最短路径。
以下是一些常见的最短路径算法:
1. Dijkstra算法:这是一种用于在图中查找单源最短路径的算法。
其主要思想是从源点开始,每次从未访问过的节点中选择距离最短的节点,然后更新其邻居节点的距离。
这种算法不能处理负权重的边。
2. Bellman-Ford算法:这种算法可以处理带有负权重的边,并且可以找到从源点到所有其他节点的最短路径。
其主要思想是通过反复松弛所有边来找到最短路径。
如果图中存在负权重的循环,则该算法可能无法找到最短路径。
3. Floyd-Warshall算法:这是一种用于查找所有节点对之间的最短路径的算法。
其主要思想是通过逐步添加中间节点来找到最短路径。
这种算法的时间复杂度较高,为O(n^3),其中n是图中的节点数。
4. A(A-Star)算法:这是一种启发式搜索算法,用于在图中找到最短路径。
它使用启发式函数来指导搜索方向,通常可以更快地找到最短路径。
A算法的关键在于启发式函数的选择,该函数应该能够准确地估计从当前节点到目标节点的距离。
这些算法都有其各自的优点和缺点,具体选择哪种算法取决于具体的问题和场景。
弗洛伊德(Floyd)算法

弗洛伊德(Floyd)算法最短路径问题:从某个顶点出发到达另外⼀个顶点的所经过的边的权重和最⼩的⼀条路径弗洛伊德算法解决最短路径问题1.基本思想(1)计算图中各个顶点之间的最短路径,每⼀个顶点都是出发访问点,所以需要将每⼀个顶点看做被访问顶点,求出从每⼀个顶点到其他顶点的最短路径(2)所有顶点都作为中间节点遍历⼀次,每次遍历将各个顶点经过中间节点到另⼀个节点的距离,与不经过该节点的距离相⽐较,若经过中间节点的距离更⼩,就更新距离表与前驱关系(3)时间复杂度O(n3),所有顶点作为出发点、中间节点、终点,每个顶点都要遍历3次2.步骤(1)设置顶点 a 到顶点 b 的最短路径已知为 L ab,顶点 b 到 c 的最短路径已知为 L bc,顶点 a 到 c 的路径为 L ac,则 a 到 c 的最短路径为:min ( ( L ab + L bc ), L ac ),b 的取值为图中所有顶点,则可获得 a 到 b 的最短路径(2)⾄于 a 到 b 的最短路径 L ab或者 b 到 c 的最短路径 L bc,是以同样的⽅式获得(3)三个点为同⼀顶点时:中间顶点为⾃⾝;三个点是不同顶点时:中间顶点是终点的前驱节点;两个顶点直接连通时:中间节点为出发点代码实现import java.util.Arrays;public class Floyd {//弗洛伊德算法解决最短路径问题public static final int BLOCK = 65535;//表⽰顶点之间不直接连通public static void main(String[] args) {char[] vertex = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};//顶点到⾃⾝距离为0int[][] matrix = {{0, 5, 7, BLOCK, BLOCK, BLOCK, 2},{5, 0, BLOCK, 9, BLOCK, BLOCK, 3},{7, BLOCK, 0, BLOCK, 8, BLOCK, BLOCK},{BLOCK, 9, BLOCK, 0, BLOCK, 4, BLOCK},{BLOCK, BLOCK, 8, BLOCK, 0, 5, 4},{BLOCK, BLOCK, BLOCK, 4, 5, 0, 6},{2, 3, BLOCK, BLOCK, 4, 6, 0}};Graph graph = new Graph(matrix, vertex);graph.floyd();graph.result();}}//带权⽆向图class Graph {public char[] vertex;//存放顶点public int[][] matrix;//保存各个顶点到其它顶点的距离,初始为直接连接的距离,算法计算后为最短距离public int[][] relay;//保存中间结点//构造器public Graph(int[][] matrix, char[] vertex) {this.vertex = vertex;this.matrix = matrix;this.relay = new int[vertex.length][vertex.length];//三个点为同⼀顶点时:中间顶点为⾃⾝;三个点是不同顶点时:中间顶点是终点的前驱节点;两个顶点直接连通时:中间节点为出发点for (int i = 0; i < vertex.length; i++) {Arrays.fill(relay[i], i);//初始中间顶点为⾃⾝}}//显⽰算法结果public void result() {for (int k = 0; k < vertex.length; k++) {for (int i = 0; i < vertex.length; i++) {System.out.println(vertex[k] + " 到 " + vertex[i] +" 最短路径 " + matrix[k][i] +" 中间结点 " + vertex[relay[k][i]]);}System.out.println();}}//弗洛伊德算法public void floyd() {int temp;//保存i到j的距离for (int i = 0; i < matrix.length; i++) {//出发点ifor (int j = 0; j < matrix.length; j++) {//中间顶点jfor (int k = 0; k < matrix.length; k++) {//终点ktemp = matrix[i][j] + matrix[j][k];//求从i出发,经过k,到达j的距离 if (temp < matrix[i][k]) {matrix[i][k] = temp;//更新距离relay[i][k] = relay[j][k];//更新中间顶点}}}}}}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
• To print the intermediate nodes on the shortest path a recursive procedure that print the shortest paths from i and k, and from k to j can be used
Floyd’s Algorithm 4
The subproblems
• Let D(k)[i,j]=weight of a shortest path from vi to vj using only vertices from {v1,v2,…,vk} as intermediate vertices in the path
1 0 0 0
D1[3,2] = min( D0[3,2], D0[3,1]+D0[1,2] ) = min (-3,) = -3
Floyd’s Algorithm 11
1
4
5
2 -3
D1 = 1
3 2 3 2 4 0 -3 2 0 0 0
1 0 2
2
2 4 0 -3
3 5 7 0
1 2 D = 2 3
ห้องสมุดไป่ตู้
D3[1,2] = min(D2[1,2], D2[1,3]+D2[3,2] ) = min (4, 5+(-3)) =2
P=
1 2 3
D3[2,1] = min(D2[2,1], D2[2,3]+D2[3,1] ) = min (2, 7+ (-1)) =2
Floyd’s Algorithm 13
1 0 2 -1 1 0 0 2
3 5 7 0 3 0 1 0
k=2 Vertices 1, 2 can be intermediate
D2[1,3] = min( D1[1,3], D1[1,2]+D1[2,3] ) = min (5, 4+7) =5
P=
1 2 3
D2[3,1] = min( D1[3,1], D1[3,2]+D1[2,1] ) = min (, -3+2) = -1
Floyd’s Algorithm 9
Example
W=
1 4 2 2 -3 P= 5
D0 =
1 2 3
1 0 2
2 4 0 -3 2 0 0 0
3 5
0 3 0 0 0
3
1 2 3
1 0 0 0
Floyd’s Algorithm 10
1
4
5
2 -3
D0 =
3
2
1 2 3 3 5 7 0 3 0 1 0
• Since D(k)[i,j]= D(k-1)[i,j] or D(k)[i,j]= D(k-1)[i,k]+ D(k-1)[k,j]. We conclude: D(k)[i,j]= min{ D(k-1)[i,j], D(k-1)[i,k]+ D(k-1)[k,j] }.
Shortest path using intermediate vertices {V1, . . . Vk } Vk
Floyd’s Algorithm 12
1
4
2
D2 = 1 1 0 3 2 2 2 -3 3 -1
5
2 4 0 -3 3 5 7 0 3 0 1 0
3 5 7 0
D3 =
1 2 3
1 0 2 -1 1 0 0 2
2 2 0 -3 2 3 0 0
k=3 Vertices 1, 2, 3 can be intermediate
The subproblems
• How can we define the shortest distance di,j in terms of “smaller” problems?
• One way is to restrict the paths to only include vertices from a restricted subset. • Initially, the subset is empty. • Then, it is incrementally increased until it includes all the vertices.
– D(0)=W – D(n)=D which is the goal matrix • How do we compute D(k) from D(k-1) ?
Floyd’s Algorithm 5
The Recursive Definition:
Case 1: A shortest path from vi to vj restricted to using only vertices from {v1,v2,…,vk} as intermediate vertices does not use vk. Then D(k)[i,j]= D(k-1)[i,j]. Case 2: A shortest path from vi to vj restricted to using only vertices from {v1,v2,…,vk} as intermediate vertices does use vk. Then D(k)[i,j]= D(k-1)[i,k]+ D(k-1)[k,j].
1 0 2
2 4 0 -3
3 5
0
1 1 D = 2 3
1 0 2
2 4 0 -3 2 0 0 0
k=1 Vertex 1 can be intermediate node
D1[2,3] = min( D0[2,3], D0[2,1]+D0[1,3] ) = min (, 7) =7
P=
1 2 3
Vi
Vj
Shortest Path using intermediate vertices { V1, . . . Vk -1 }
Floyd’s Algorithm 7
The pointer array P
• Used to enable finding a shortest path • Initially the array contains 0
Floyd’s Algorithm 8
Floyd's Algorithm Using n+1 D matrices
Floyd//Computes shortest distance between all pairs of //nodes, and saves P to enable finding shortest paths 1. D0 W // initialize D array to W [ ] 2. P 0 // initialize P array to [0] 3. for k 1 to n 4. do for i 1 to n 5. do for j 1 to n 6. if (Dk-1[ i, j ] > Dk-1 [ i, k ] + Dk-1 [ k, j ] ) 7. then Dk[ i, j ] Dk-1 [ i, k ] + Dk-1 [ k, j ] 8. P[ i, j ] k; 9. else Dk[ i, j ] Dk-1 [ i, j ]
Shortest path using intermediate vertices {V1, . . . Vk } Vk
Vi
Vj
Shortest Path using intermediate vertices { V1, . . . Vk -1 }
Floyd’s Algorithm 6
The recursive definition
Floyd’s Algorithm 2
The weight matrix and the graph
1
1 2 3 4 5
1 0 9 3
2 1 0
3 3 0 2
4 1 2 4 0
5 5 3 0
v5
3 5 3
v1 1 v4
9 2 2 4
v2 3 v3
Floyd’s Algorithm 3
Floyd’s Algorithm
All pairs shortest path
Floyd’s Algorithm 1
All pairs shortest path
• The problem: find the shortest path between every pair of vertices of a graph • The graph: may contain negative edges but no negative cycles • A representation: a weight matrix where W(i,j)=0 if i=j. W(i,j)= if there is no edge between i and j. W(i,j)=“weight of edge” • Note: we have shown principle of optimality applies to shortest path problems