In computer science, Floyd Warshall algorithm is an algorithm to find the shortest path in a weighted graph with positive or negative edge weight (but no negative period).A single execution of the algorithm will find the length (weighted) of the shortest path between all vertex pairs.Although it does not return the details of the path itself, it can reconstruct the path by simply modifying the algorithm.The version of the algorithm can also be used to find the transitive closure of relation R, or (related to Schulze voting system) the widest path between all vertex pairs in the weighted graph.
Floyd Warshall algorithm isdynamic programmingAnd was published in 1962 by Robert Floyd in his currently recognized form.However, it is basically the same as the algorithm previously published by Bernard Roy in 1959 and the transitive closure of graphs found in Stephen Warshall in 1962, and is closely related to Kleene's algorithm in 1956)Finite automatonConvert to regular expression.The algorithm was first described by Peter Ingerman in 1962 as a modern formula for three nested for loops.
This algorithm is also called Floyd algorithm, Roy Warshall algorithm, Roy Floyd algorithm or WFI algorithm.[2]
Weighted subordinate graphadjacency matrix A=[a (i, j)] n × n, iteratively update n times, that is, from matrix D (0)=A, according to a formula, construct matrix D (1);D (2) is constructed from D (1) by the same formula;Finally, the matrix D (n) is constructed from D (n-1) with the same formula.The elements in row i and column j of matrix D (n) are the shortest path length from vertex i to vertex j, and D (n) is called graphDistance matrixAt the same time, a successor node matrix path can be introduced to record the shortest path between two points.
Adopt relaxation technology(Relax operation), all other points between i and j are relaxed once.So the time complexity is O (n ^ 3);
Map [i, j] indicates the shortest distance from i to j, and K is exhaustivei. Of jFor breakpoints, the initial value of map [n, n] should be 0, or follow the meaning of the topic.
Of course, if this path is not available, special processing must be done, for example, there is no map [i, k] path.
Algorithmic process
Announce
edit
1. Start from any unilateral path.The distance between all two points is the weight of the edge. If there is no edge between the two points, the weight is infinite.
2. For each pair of vertices u and v, check whether there is a vertex w that makes the path from u to w and then to v shorter than the known path.If it is updated.
The graph is represented by the adjacency matrix G. If there is a path from Vi to Vj, then G [i] [j]=d, and d represents the length of the path;Otherwise, G [i] [j]=infinity.Define a matrix D to record the information of the inserted point. D [i] [j] represents the point that needs to pass from Vi to Vj. Initialize D [i] [j]=j.Insert each vertex into the graph and compare the distance after inserting the vertex with the original distance. G [i] [j]=min (G [i] [j], G [i] [k]+G [k] [j]). If the value of G [i] [j] becomes smaller, D [i] [j]=k.G contains the information about the shortest path between two points, while D contains the information about the shortest path.
For example, you need to find the path from V5 to V1.According to D, if D (5,1)=3, it means that the path from V5 to V1 is {V5, V3, V1}. If D (5,3)=3, it means that V5 is directly connected to V3. If D (3,1)=1, it means that V3 is directly connected to V1.[4]
Floyd algorithm is applicable to APSP (All Pairs Shortest Paths), which is a dynamic programming algorithm,Dense graphThe effect is the best, and the edge weight can be positive or negative.This algorithm is simple and effective. Due to the compact structure of the triple loop, it is more efficient than executing | V | times for dense graphsDijkstra algorithm, which is also higher than executing | V | timesSPFA algorithm。
Advantages: easy to understand, the shortest distance between any two nodes can be calculated, and the code is simple to write.
Disadvantages: The time complexity is relatively high, and it is not suitable for calculating a large amount of data.[5]
Algorithm description
Announce
edit
a) Initialization: D [u, v]=A [u, v]
b) For k:=1 to n
For i:=1 to n
For j:=1 to n
If D[i,j]>D[i,k]+D[k,j] Then
D[i,j]:=D[i,k]+D[k,j];
c) Algorithm end: D is the shortest path matrix of all point pairs
Reference code
Announce
edit
C language
#include<stdio.h>#include<stdlib.h>#define max 1000000000int d[1000][1000],path[1000][1000];int main(){ int i,j,k,m,n; int x,y,z; scanf("%d%d",&n,&m); for(i=1;i<=n;i++) for(j=1;j<=n;j++){ d[i][j]=max; path[i][j]=j; } for(i=1;i<=m;i++) { scanf("%d%d%d",&x,&y,&z); d[x][y]=z; d[y][x]=z; } for(k=1;k<=n;k++) for(i=1;i<=n;i++) for(j=1;j<=n;j++) { if(d[i][k]+d[k][j]<d[i][j]) { d[i][j]=d[i][k]+d[k][j]; path[i][j]=path[i][k]; } } for(i=1;i<=n;i++) for(j=1;j<=i;j++) if (i!=j) printf("%d->%d:%d\n",i,j,d[i][j]); int f, en; scanf("%d%d",&f,&en); while (f!=en) { printf("%d->",f); f=path[f][en]; } printf("%d\n",en); return 0;}
C++Language
#include<iostream>#include<vector>using namespace std;const int &INF=100000000;Void floyd (vector<vector<int>>&distmap,//the adjacency matrix that can be updated, and the original edge cannot be determined after the updateVector<vector<int>>&path)//The transit point on the path to the point//Welfare: This function does not use any global quantity except INF, and can be copied directly!{ const int &NODE=distmap.size();//Use the size of the adjacency matrix to transfer the number of vertices to reduce parameter transfer path.assign(NODE,vector<int>(NODE,-1));//Initialization path arrayFor (int k=1; k!=NODE;++k)//For each transit pointFor (int i=0; i!=NODE;++i)//Enumerate source pointsFor (int j=0; j!=NODE;++j)//Enumerate endpointsIf (distmap [i] [j]>distmap [i] [k]+distmap [k] [j])//does not satisfy the triangular inequality { distmap[i][j]=distmap[i][k]+distmap[k][j];//to update path[i][j]=k;//Record Path }}void print(const int &beg,const int &end,Const vector<vector<int>>&path)//Transfer reference, avoid copying, and do not occupy memory space//You can also use the stack structure to replace function recursion{ if(path[beg][end]>=0) { print(beg,path[beg][end],path); print(path[beg][end],end,path); } else cout<<"->"<<end;}int main(){Int n_num, e_num, berg, end;//The meaning is as followsCout<<"(Negative weight circuit is not processed) Input number of points and sides:"; cin>>n_num>>e_num; vector<vector<int> > path,Distmap (n_num, vector<int>(n_num, INF));//By default, the adjacency matrix is initialized for(int i=0,p,q; i!=e_num; ++i) {Cout<<"Input the start point, end point and length of the"<<i+1<<"edge (100000000 represents infinity, not connected):"; cin>>p>>q; cin>>distmap[p][q]; } floyd(distmap,path);Cout<<"After calculation, query can be started. Please enter the starting point and destination:"; cin>>beg>>end;Cout<<"The shortest distance is"<<distmap [berg] [end]<<", print path:"<<berg; print(beg,end,path);}
Matlab source code
function Floyd(w,router_direction,MAX)%W is the distance matrix of this figure%Router_direction is the route type: 0 is the forward route;Non 0 is backtracking route%MAX is the actual value of ∞ when data is inputlen=length(w);flag=zeros(1,len);%Initialize the routing table according to the routing typeR=zeros(len,len);for i=1:lenIf router_direction==0% forward routingR(:,i)=ones(len,1)*i;Else% backtracking routeR(i,:)=ones(len,1)*i;endR(i,i)=0;enddisp('');disp('w(0)');dispit(w,0);disp('R(0)');dispit(R,1);%Handle the issue of endpoint ownershipfor i=1:lentmp=w(i,i)/2;if tmp~=0w(i,:)=w(i,:)+tmp;w(:,i)=w(:,i)+tmp;flag(i)=1;w(i,i)=0;endend%Specific implementation process of Floyd algorithmfor i=1:lenfor j=1:lenif j==i || w(j,i)==MAXcontinue;endfor k=1:lenif k==i || w(j,i)==MAXcontinue;endIf w (j, i)+w (i, k)<w (j, k)% Floyd algorithm core codew(j,k)=w(j,i)+w(i,k);If router_direction==0% forward routingR(j,k)=R(j,i);Else% backtracking routeR(j,k)=R(i,k);endendendend%Display each calculation resultdisp(['w(',num2str(i),')'])dispit(w,0);disp(['R(',num2str(i),')'])dispit(R,1);end%Determination of center and midpoint[Center,index]=min(max(w'));Disp (['center is V ', num2str (index)]);[Middle,index]=min(sum(w'));Disp (['The midpoint is V ', num2str (index)]);endfunction dispit(x,flag)%x: Matrix to be displayed%Flag: If it is 0, the w matrix is displayed; if it is not 0, the R matrix is displayedlen=length(x);s=[];for j=1:lenif flag==0s=[s sprintf('%5.2f\t',x(j,:))];elses=[s sprintf('%d\t',x(j,:))];ends=[s sprintf('\n')];enddisp(s);disp('---------------------------------------------------');end%After selecting, press Ctrl+t to cancel the comment number%%%Example:% a=[% 0,100,100,1.2,9.2,100,0.5;% 100,0,100,5,100,3.1,2;% 100,100,0,100,100,4,1.5;% 1.2,5,100,0,6.7,100,100;% 9.2,100,100,6.7,0,15.6,100;% 100,3.1,4,100,15.6,0,100;% 0.5,2,1.5,100,100,100,0% ];%% b=[% 0,9.2,1.1,3.5,100,100;% 1.3,0,4.7,100,7.2,100;% 2.5,100,0,100,1.8,100;% 100,100,5.3,0,2.4,7.5;% 100,6.4,2.2,8.9,0,5.1;% 7.7,100,2.7,100,2.1,0% ];%% Floyd(a,1,100)% Floyd(b,1,100)
Pascal language
program floyd;varst,en,f:integer;k,n,i,j,x:integer;a:array[1..10,1..10] of integer;path:array[1..10,1..10] of integer;beginreadln(n);for i:=1 to n dobeginfor j:=1 to n dobeginread(k);if k<>0 thena[i,j]:=kelsea[i,j]:=maxint;path[i,j]:=j;end;readln;end;for x:=1 to n dofor i:=1 to n dofor j:=1 to n doif a[i,j]>a[i,x]+a[x,j] thenbegina[i,j]:=a[i,x]+a[x,j];path[i,j]:=path[i,x];end;readln(st,en);writeln(a[st,en]);f:=st;while f<> en dobeginwrite(f);write('-->');f:=path[f,en];end;writeln(en);end.
Java language
//Using undirected graph G as the entry, we can get the path length [i] [j], path [i] [j] [k] between any two points,//The distance between points without connection on the way is indicated by 0, and the point itself is also indicated by 0public class FLOYD {int[][] length = null;//Path length between any two pointsint[][][] path = null;//Path between any two pointspublic FLOYD(int[][] G) {int MAX = 100;int row = G.length;//Number of rows in graph Gint[][] spot = new int[row][row];//Define the point that passes between any two pointsint[] onePath = new int[row];//Record a pathlength = new int[row][row];path = new int[row][row][];For (int i=0; i<row; i++)//Process the path between two points in the figurefor (int j = 0; j < row; j++) {if (G[i][j] == 0)G[i][j] = MAX;//The path between two points without a path is the default maximumif (i == j)G[i][j] = 0;//Its path length is 0}For (int i=0; i<row; i++)//Initialize to no path between any two pointsfor (int j = 0; j < row; j++)spot[i][j] = -1;For (int i=0; i<row; i++)//Assume that there is no path between any two pointsonePath[i] = -1;for (int v = 0; v < row; ++v)for (int w = 0; w < row; ++w)length[v][w] = G[v][w];for (int u = 0; u < row; ++u)for (int v = 0; v < row; ++v)for (int w = 0; w < row; ++w)if (length[v][w] > length[v][u] + length[u][w]) {length[v][w] = length[v][u] + length[u][w];//If there is a shorter path, take the shorter pathspot[v][w] = u;//Add the passing points}For (int i=0; i<row; i++) {//Find all pathsint[] point = new int[1];for (int j = 0; j < row; j++) {point[0] = 0;onePath[point[0]++] = i;outputPath(spot, i, j, onePath, point);path[i][j] = new int[point[0]];for (int s = 0; s < point[0]; s++)path[i][j][s] = onePath[s];}}}Void outputPath (int [] [] spot, int i, int j, int [] onePath, int [] point) {//Output the actual code of the path i//to j//, and point [] records the length of a pathif (i == j)return;if (spot[i][j] == -1)onePath[point[0]++] = j;// System.out.print(" "+j+" ");else {outputPath(spot, i, spot[i][j], onePath, point);outputPath(spot, spot[i][j], j, onePath, point);}}public static void main(String[] args) {int data[][] = {{ 0, 27, 44, 17, 11, 27, 42, 0, 0, 0, 20, 25, 21, 21, 18, 27, 0 },// x1{ 27, 0, 31, 27, 49, 0, 0, 0, 0, 0, 0, 0, 52, 21, 41, 0, 0 },// 1{ 44, 31, 0, 19, 0, 27, 32, 0, 0, 0, 47, 0, 0, 0, 32, 0, 0 },// 2{ 17, 27, 19, 0, 14, 0, 0, 0, 0, 0, 30, 0, 0, 0, 31, 0, 0 },// 3{ 11, 49, 0, 14, 0, 13, 20, 0, 0, 28, 15, 0, 0, 0, 15, 25, 30 },// 4{ 27, 0, 27, 0, 13, 0, 9, 21, 0, 26, 26, 0, 0, 0, 28, 29, 0 },// 5{ 42, 0, 32, 0, 20, 9, 0, 13, 0, 32, 0, 0, 0, 0, 0, 33, 0 },// 6{ 0, 0, 0, 0, 0, 21, 13, 0, 19, 0, 0, 0, 0, 0, 0, 0, 0 },// 7{ 0, 0, 0, 0, 0, 0, 0, 19, 0, 11, 20, 0, 0, 0, 0, 33, 21 },// 8{ 0, 0, 0, 0, 28, 26, 32, 0, 11, 0, 10, 20, 0, 0, 29, 14, 13 },// 9{ 20, 0, 47, 30, 15, 26, 0, 0, 20, 10, 0, 18, 0, 0, 14, 9, 20 },// 10{ 25, 0, 0, 0, 0, 0, 0, 0, 0, 20, 18, 0, 23, 0, 0, 14, 0 },// 11{ 21, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 0, 27, 22, 0, 0 },// 12{ 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0 },// 13{ 18, 41, 32, 31, 15, 28, 0, 0, 0, 29, 14, 0, 22, 0, 0, 11, 0 },// 14{ 27, 0, 0, 0, 25, 29, 33, 0, 33, 14, 9, 14, 0, 0, 11, 0, 9 },// 15{ 0, 0, 0, 0, 30, 0, 0, 0, 21, 13, 20, 0, 0, 0, 0, 9, 0 } // 16};for (int i = 0; i < data.length; i++)for (int j = i; j < data.length; j++)if (data[i][j] != data[j][i])return;FLOYD test=new FLOYD(data);for (int i = 0; i < data.length; i++)for (int j = i; j < data[i].length; j++) {System.out.println();System.out.print("From " + i + " to " + j + " path is: ");for (int k = 0; k < test.path[i][j].length; k++)System.out.print(test.path[i][j][k] + " ");System.out.println();System.out.println("From " + i + " to " + j + " length :"+ test.length[i][j]);}}}