This algorithm was published by Robert W. Floyd (Robert Floyd) in 1962 on "Communications of the ACM". That same year Stephen Warshall (Stephen Vauchers) also published the algorithm independently. Robert W.. Floyd This cow man is a wonderful, he originally read the literature at the University of Chicago, but because the American economy is not very prosperous, find a job more difficult, helpless to Westinghouse Electric Company when a computer operator, in the IBM650 room night, and thus began his computer career.
-
Ahalei Source: 51CTO Blog |
2014-03-26 09:04
-
Mobile collection Sharing
Summer vacation, Xiao Hum ready to go to some city tour. Some cities have highways, and some cities do not, such as. To save money and make it easier to plan your trip, Xiao Hum hopes to know the shortest distance before departing any two cities before departure.
There are 8 highways in 4 cities, and the numbers on the highways indicate the length of the road. Please note that these highways are one-way. We now need to find the shortest distance between any two cities, that is, the shortest path between any two points. This problem is also known as the "multi-source Shortest path" problem.
Now we need a data structure to store the information of the graph, we can still use a 4*4 matrix (two-dimensional array e) to store. For example, City 1th to City 2nd is 2, then set e[1][2] to a value of 2. City No. 2nd cannot reach City 4th, the value of setting e[2][4] is ∞. In addition here the Convention a city itself is to own also 0, for example E[1][1] for 0, specifically as follows.
Now back to the question: how to find the shortest path between any two points? Through previous studies we know that the shortest path between two points can be found through depth or breadth-first search. So n2 the depth or breadth of the first search, that is, every two points of a depth or breadth first search, you can find any two points between the shortest path. But is there any other way?
Let's think about it, according to our previous experience, if you want to shorten the distance between any two points (for example, from vertex A to vertex B), you can only introduce a third point (vertex K) and pass through this vertex K relay, which is a->k->b, which may reduce the original distance from vertex A to vertex b. So what is the point in the 1~n that this relay vertex k is? Sometimes it is even shorter to pass through two or more points, not just through a point, a->k1->k2b-> or a->k1->k2...->k->i...->b. For example, the distance from city 4th to City 3rd (4->3) e[4][3] was originally 12. If you only pass through City 1th (4->1->3), the journey will be shortened to one (e[4][1]+e[1][3]=5+6=11). In fact, City 1th to 3rd City can also transit through the city of 2nd, making the 1th to 3rd city journey shortened to 5 (e[1][2]+e[2][3]=2+3=5). So if you go through two cities at 1th and 2nd, the distance from city 4th to City 3rd will be shortened to 10. With this example, we find that each vertex has the potential to shorten the distance between the other two vertices. OK, let's generalize this question.
When a third point is not allowed between any two points, the shortest distance between these cities is the initial distance, as follows.
What if the shortest distance between any two points is only allowed to go through the number 1th vertex? Just determine if E[I][1]+E[1][J] is smaller than e[i][j]. E[I][J] represents the distance from the I vertex to the J number vertex. E[I][1]+E[1][J] Represents the sum of the distances from vertex i to number 1th, and from vertex number 1th to vertex J. Where I is the 1~n loop, and J is also the 1~n loop, the code is implemented as follows.
- 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];
- }
- }
In cases where only 1th vertices are allowed, the shortest distance between any two points is updated to:
We found that the distances from vertex 3rd to vertex 2nd (e[3][2]), vertex 4th to Vertex 2nd (e[4][2]), and 4th vertices to 3rd vertices (e[4][3]) were shortened when only the 1th vertices were brokered.
Next, continue to ask for the shortest distance between any two points that only allow two vertices of 1 and 2nd. How to do it? We need to be able to take the shortest distance of any two points when only the 1th vertex is allowed, and then determine if passing the vertex number 2nd will make the distance between the I vertex and the J vertex shorter. That is to judge E[i][2]+e[2][j] is smaller than e[i][j], the code is implemented as follows.
- After vertex number 1th
- 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];
- After vertex number 2nd
- For (i=1;i<=n;i++)
- For (j=1;j<=n;j++)
- if (E[i][j] > e[i][2]+e[2][j]) e[i][j]=e[i][2]+e[2][j];
In cases where only 1 and 2nd vertices are allowed, the shortest distance between any two points is updated to:
By knowing that, when compared to only allowing transit through the number 1th vertices, this allows the transfer through vertices 1 and 2nd, making e[1][3] and e[4][3] shorter distances.
In the same vein, the shortest distance between any two points is continued in cases where only 1, 2, and 3rd vertices are allowed to be brokered. The shortest distance between any two points is updated as follows:
Finally, all vertices are allowed as a transit, and the final shortest distance between any two points is:
The entire algorithm process, though cumbersome, but the code implementation is very simple, the core code only five elements:
- For (k=1;k<=n;k++)
- For (i=1;i<=n;i++)
- For (j=1;j<=n;j++)
- if (E[i][j]>e[i][k]+e[k][j])
- E[I][J]=E[I][K]+E[K][J];
The basic idea of this code is that it is only allowed to go through the number 1th vertices at first, and then only the 1 and 2nd vertices are allowed to relay ... The shortest distance between any two points is allowed through all vertices of the 1~n number. In a nutshell: From the I vertex to the J vertex only passes the shortest distance from the front K points. In fact, this is a "dynamic planning" of the idea, about this idea we will be in the "Aha!" The algorithm 2--the great thinking shines in a detailed discussion. The complete code for this algorithm is given below:
- #include <stdio.h>
- int main ()
- {
- int e[10][10],k,i,j,n,m,t1,t2,t3;
- int inf=99999999; //Use INF (infinity abbreviation) to store a positive infinity value we think
- //Read in N and m,n to indicate the number of vertices, m represents the number of edges
- scanf ("%d%d", &n,&m);
- //Initialize
- For (i=1;i<=n;i++)
- For (j=1;j<=n;j++)
- if (i==j) e[i][j]=0;
- else E[i][j]=inf;
- //read in side
- For (i=1;i<=m;i++)
- {
- scanf ("%d%d%d", &T1,&T2,&T3);
- E[T1][T2]=T3;
- }
- //floyd-warshall algorithm Core statement
- For (k=1;k<=n;k++)
- For (i=1;i<=n;i++)
- For (j=1;j<=n;j++)
- if (E[i][j]>e[i][k]+e[k][j])
- E[I][J]=E[I][K]+E[K][J];
- //Output The final result
- For (i=1;i<=n;i++)
- {
- For (j=1;j<=n;j++)
- {
- printf ("%10d", E[i][j]);
- }
- printf ("\ n");
- }
- return 0;
- }
One thing to note is: How to represent positive infinity. We typically define positive infinity as 99999999, because so even if two positive infinity is added, its sum still does not exceed the range of type int (the maximum positive integer that the C language int type can store is 2147483647). In practical applications it is best to estimate the upper limit of the shortest path, just set a bit larger than it can be. For example, with 100 edges and no more than 100 on each side, just set the positive infinity to 10001. If you think positive infinity and other values add up to a number greater than the positive infinity is not allowed, we only need to add two judgment conditions when comparing, please note the underlined statement in the following code.
- Floyd-warshall Algorithm Core statement
- For (k=1;k<=n;k++)
- For (i=1;i<=n;i++)
- For (j=1;j<=n;j++)
- if (e[i][k]<inf && e[k][j]<inf && e[i][j]>e[i][k]+e[k][j])
- E[I][J]=E[I][K]+E[K][J];
The input data style for the above code is:
- 4 8
- 1 2 2
- 1 3 6
- 1 4 4
- 2 3 3
- 3 1 7
- 3 4 1
- 4 1 5
- 4 3
The first row of two numbers is N and M,n represents the number of vertices, and m represents the number of edges.
The next m line, each row has three numbers T1, T2, and T3, indicating that the vertex t1 to the vertex t2 the distance is T3.
Get the final result as follows:
By this method we can find the shortest path between any two points. Its time complexity is O (N3). What is shocking is that it has only five lines of code, it is very easy to achieve. Precisely because it is very easy to implement, if time complexity is not required, it is possible to use Floyd-warshall to specify the shortest path between two points or to specify a point to the rest of each vertex. Of course there are faster algorithms, see the next section: Dijkstra algorithm.
It is also important to note that the Floyd-warshall algorithm cannot solve a graph with a "negative weight loop" (or "negative weight loop") because there is no shortest path with a "negative weight loop" diagram. For example, the following figure does not have the shortest path from vertex number 1th to vertex 3rd. Because 1->2->3->1->2->3->...->1->2->3 such a path, each time around a 1->-2>3 such a ring, the shortest path will be reduced by 1, never find the shortest way. In fact, if a figure with a "negative weight loop" then this diagram is not the shortest way.
This algorithm was published by Robert W. Floyd (Robert Floyd) in 1962 on "Communications of the ACM". That same year Stephen Warshall (Stephen Vauchers) also published the algorithm independently. Robert W.. Floyd This cow man is a wonderful, he originally read the literature at the University of Chicago, but because the American economy is not very prosperous, find a job more difficult, helpless to Westinghouse Electric Company when a computer operator, in the IBM650 room night, and thus began his computer career. In addition, he and J.W.J Williams in 1964 jointly invented the famous heap sorting algorithm heapsort. Heap Sorting algorithm We will study in the seventh chapter. Robert W.. Floyd won the Turing Award in 1987.
Floyd algorithm to find any shortest circuit