The principle and implementation of Floyd algorithm

Source: Internet
Author: User

I. Introduction to Algorithms

The Floyd algorithm is an algorithm for finding the shortest path in a graph. The Floyd algorithm can be used to solve the shortest path in a forward graph with negative weights compared to a Dijkstra algorithm that cannot have negative weights in the graph (although it cannot contain a negative weight loop). It is an algorithm for solving the shortest path between the midpoint and the point of a graph.

We check for each node x in the graph, for 2 points A and B in the graph, if there is dis (ax) +dis (XB) <dis (AB), then the DIS (AB) =dis (AX) +dis (XB). When all nodes x is traversed, the shortest path of AB is obtained.

So, the core code is simple, where N is the number of vertices, the time complexity is O (n^3)

Note the nesting order of 3 for loops

void Floyd (int N) {int i,j,k;for (k=0;k<n;k++) {for (i=0;i<n;i++) {for (j=0;j<n;j++) {if (Dis[i][k]+dis[k][j] <dis[i][j]) {dis[i][j]=dis[i][k]+dis[k][j];}}}}
Two. Principle of the algorithm

The principle of Floyd algorithm is a kind of dynamic programming idea.

Set Ak(I,J) to indicate the shortest path from the I-point to the J-point index number not greater than K.

The shortest path is obtained, which can be expressed as

for (k=0;k<n;k++)

Then, in turn, A0 (i,j) , A1 (i,j), ..., an (i,j), where A0 (I,j) represents the diagram at the time of initialization

In this process, we must first seek A0 (I,J) to seek A1 (I,J), and then A2 (i,j) ..... So this is a bottom-up design idea, why first ask A0 (I,J) to seek A1 (I,J), and then A2 (i,j) ...

Because the algorithm is running this way.

We can be style= by a k a k-1A SUP style= "FONT-FAMILY:VERDANA,SANS-SERIF; line-height:21px; Orphans:2; Widows:2 ">k

first:

a k (i,j) without dot K , at which point

a k (I,J) =< Span style= "FONT-FAMILY:VERDANA,SANS-SERIF; font-size:14px; line-height:21px ">a K-1 (I,J)

second type:

a k (I,J) after a bit of K , at which point

a k (I,J) =< Span style= "FONT-FAMILY:VERDANA,SANS-SERIF; font-size:14px; line-height:21px ">a K-1 (i,k) +< Span style= "FONT-FAMILY:VERDANA,SANS-SERIF; font-size:14px; line-height:21px ">a K-1 (I,K)

Because after K, so this time the path is divided into 2 parts, part from I to K, the other part is K, to J, because K at this time has been as the beginning or end of the 2-part path, so at this time the shortest path required for this 2 part, is to use Ak-1(i,k) and A k-1(i,k). This is a DP idea.

So in 2 cases, I'm going to end up picking the one with the path broken,

SoAk(i,j) = min (ak-1(i,j), ak-1(i,k) + ak-1(k,j))

This step actually corresponds to the code section:

if (Dis[i][k]+dis[k][j]<dis[i][j]) {   dis[i][j]=dis[i][k]+dis[k][j];}
Three: Print path

Use Path[i][j] to record path information.

Suppose we exist path 1→5→7→9, then seek path[1][9]=7 first, then seek path[1][7]=5, then seek path[1][5]=1.

Therefore, the algorithm should be replaced by adding path[i][j]=k, because when the path is updated, the path is in the K point, so record it

void Floyd (int N) {int i,j,k;for (k=0;k<n;k++) {for (i=0;i<n;i++) {for (j=0;j<n;j++) {if (Dis[i][k]+dis[k][j] <dis[i][j]) {dis[i][j]=dis[i][k]+dis[k][j];p ath[i][j]=k;}}}}
PATH[I][J] Initialization code:

At first, we assumed that any 2 points in the graph were connected.

for (i=0;i<n;i++) {for (j=0;j<n;j++) {path[i][j]=i;}}
Four: Source code
The code stores the graph with an adjacency matrix, and the input 1000 indicates that 2 vertices are unreachable (unlimited weights)

#include <iostream> #include <stack>using namespace std; #define MAX 1000int Graph[max][max];int dis[max][ MAX]; #define Infinite 1000int path[max][max];void Floyd (int N) {int i,j,k;for (k=0;k<n;k++) {for (i=0;i<n;i++) {for (j=0;j<n;j++) {if (Dis[i][k]+dis[k][j]<dis[i][j]) {dis[i][j]=dis[i][k]+dis[k][j];p ath[i][j]=k;}}}} void Print_path (int N) {int i,j;for (i=0;i<n;i++) {for (j=0;j<n;j++) {if ((i!=j) &&dis[i][j]!=infinite) { cout<<i+1<< "----" <<j+1<< "Distance:" <<Dis[i][j]<<endl;cout<< "Path:" <<endl;int k=j;stack <int> ph;do{k=path[i][k];p H.push (k);} while (k!=i), Cout<<ph.top () +1;ph.pop (), while (!ph.empty ()) {cout<< "--" <<ph.top () +1;ph.pop ();} cout<< "," <<j+1<<endl;}}} void Main () {int n,i,j;cin>>n;for (i=0;i<n;i++) {for (j=0;j<n;j++) {int g;cin>>g; Graph[i][j]=g;dis[i][j]=g;}} Initialize path for (i=0;i<n;i++) {for (j=0;j<n;j++) {path[i][j]=i;}}    Floyd (N);p Rint_path (n); System("pause"); 

Diagram used for testing:


Test results:




The principle and implementation of Floyd algorithm

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.