Floyd algorithm

Mathematical noun
Collection
zero Useful+1
zero
Floyd algorithm, also known as interpolation method, is a method of using dynamic programming The idea of looking for a given Weighted graph Between multiple source points in Shortest path Algorithm, and Dijkstra algorithm similar. This algorithm is named after one of the founders Turing Award Winner Stanford University Professor of Computer Science Department Robert W. Floyd Naming. [1]
Chinese name
Freud algorithm
Foreign name
Floyd(Floyd-Warshall)
Alias
Roy Warshall algorithm
Time complexity
O(n^3)
Spatial complexity
O(n^2)
Role
Find the shortest path of multiple sources and transitive closure

brief introduction

Announce
edit
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 is dynamic programming And 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 automaton Convert 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]

Core ideas

Announce
edit

Path matrix

Through the weight of a graph matrix Find the Shortest path Matrix. [3]
Weighted subordinate graph adjacency 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 graph Distance matrix At 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);

State transfer equation

his State transfer equation As follows: map [i, j]:=min {map [i, k]+map [k, j], map [i, j]};
Map [i, j] indicates the shortest distance from i to j, and K is exhaustive i. Of j For 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]

Time complexity and space complexity

Announce
edit
Time complexity :O(n^3);

Advantages and disadvantages analysis

Announce
edit
Floyd algorithm is applicable to APSP (All Pairs Shortest Paths), which is a dynamic programming algorithm, Dense graph The 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 graphs Dijkstra algorithm , which is also higher than executing | V | times SPFA 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 1000000000 int 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 update Vector<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 array For (int k=1; k!=NODE;++k)//For each transit point For (int i=0; i!=NODE;++i)//Enumerate source points For (int j=0; j!=NODE;++j)//Enumerate endpoints If (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 follows Cout<<"(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 input len=length(w); flag=zeros(1,len); %Initialize the routing table according to the routing type R=zeros(len,len); for i=1:len If router_direction==0% forward routing R(:,i)=ones(len,1)*i; Else% backtracking route R(i,:)=ones(len,1)*i; end R(i,i)=0; end disp(''); disp('w(0)'); dispit(w,0); disp('R(0)'); dispit(R,1); %Handle the issue of endpoint ownership for i=1:len tmp=w(i,i)/2; if tmp~=0 w(i,:)=w(i,:)+tmp; w(:,i)=w(:,i)+tmp; flag(i)=1; w(i,i)=0; end end %Specific implementation process of Floyd algorithm for i=1:len for j=1:len if j==i || w(j,i)==MAX continue; end for k=1:len if k==i || w(j,i)==MAX continue; end If w (j, i)+w (i, k)<w (j, k)% Floyd algorithm core code w(j,k)=w(j,i)+w(i,k); If router_direction==0% forward routing R(j,k)=R(j,i); Else% backtracking route R(j,k)=R(i,k); end end end end %Display each calculation result disp(['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)]); end function 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 displayed len=length(x); s=[]; for j=1:len if flag==0 s=[s sprintf('%5.2f\t',x(j,:))]; else s=[s sprintf('%d\t',x(j,:))]; end s=[s sprintf('\n')]; end disp(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; begin readln(n); for i:=1 to n do begin for j:=1 to n do begin read(k); if k<>0 thena[i,j]:=k elsea[i,j]:=maxint; path[i,j]:=j; end; readln; end; for x:=1 to n do for i:=1 to n do for j:=1 to n do if a[i,j]>a[i,x]+a[x,j] then begin a[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 do begin write(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 0 public class FLOYD { int[][] length = null;// Path length between any two points int[][][] path = null;// Path between any two points public FLOYD(int[][] G) { int MAX = 100; int row = G.length;// Number of rows in graph G int[][] spot = new int[row][row];// Define the point that passes between any two points int[] onePath = new int[row];// Record a path length = new int[row][row]; path = new int[row][row][]; For (int i=0; i<row; i++)//Process the path between two points in the figure for (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 maximum if (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 points for (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 points onePath[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 path spot[v][w] = u;// Add the passing points } For (int i=0; i<row; i++) {//Find all paths int[] 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 path if (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]); } } }