Package Org.loda.graph;import Java.math.bigdecimal;import Java.math.roundingmode;import org.loda.util.In;/** * * @ Classname:floydwarshall * @Description: Find the shortest path between any two points in a graph * * Floydwarshall algorithm calculates the shortest path between any two points by dynamic programming * * If the shortest path is normally obtained, the Bellmanford algorithm can be used for the V (vertex number) of the graph. In this case, the time complexity is ev^2 * if it is a sparse graph, then approximate to v^3 * But if it is a dense graph, then the time complexity will approximate to v^4, this situation needs optimization, here floydwarshall through dynamic planning optimization * , and the adjacency matrix is used to represent the diagram. * d (I,J); If m=0 * D (i,j,m) ={* min (d (i,m,m-1) +d (m,j,m-1), D (i,j,m-1)); if m!=0 * @author Minjun * @date June 1, 2015 Morning 9:39:42 * */public class Floydwarshall {private double[][] d;private int[][] prev;private int v;private bool EAN negativecycle;public floydwarshall (int v) {this.v = V;d = new Double[v][v];p rev = new int[v][v];//default settings all nodes are unreachable, and themselves to is up to and distance is 0.0for (int i = 0; i < V; i++) {for (int j = 0; J < V; j + +) {D[i][j] = double.positive_infinity;prev[i][j] = -1;if (i==j) {d[i][j] = 0;}}} /** * * @Title: finDshortestpath * @Description: Query Shortest Path * @param settings file * @return void return type * @throws */public void Findshortestpath () {//Find least-shorted diameter for (int k = 0; k < V; k++) {//each k value is considered as an intermediate point in the i->j path for (int i = 0; i < V; i++) {for (int j = 0; J < V; j + +) {//If there is a weight and a smaller intermediate value K, update the shortest path to K-path if (D[i][j] > D[i][k] + d[k][j]) {d[i][j] = D[i][k] + d[k][j];p rev[i][j]=k;}}} Rounding distance for (int i = 0, i < V; i++) {for (int j = 0; J < V; j + +) {D[i][j] = new BigDecimal (D[i][j]). Setscale (2,round INGMODE.HALF_UP). Doublevalue ();}} The way to detect a negative weight ring is very simple, is to judge all i->i distance d[i][i], if there is less than 0, indicating the weight of this i->i loop and the formation of a negative value, that is, the existence of this negative weight//in the other shortest path algorithm, Negative loops cannot be detected by this method because the previous path distances are stored in a one-dimensional array, equivalent to detecting only d[0][0], and cannot detect each d[i][i]for (int i=0;i<v;i++) {if (d[i][i]<0) Negativecycle=true;}} /** * * @Title: Hasnegativecycle * @Description: Has a negative weight ring * @param @return Set File * @return Boolean return type * @throws */public Boolean hasnegativecycle () {return negativecycle;} /** * * @Title: Distto * @Description: distance of a->b Shortest path * @param @param a * @param @param b * @param @return settings file * @return Double return type * @throws */public double distto (int a, int b) {if (Hasnegativecycle ()) thro W New RuntimeException ("with negative weight ring, no shortest Path"); return d[a][b];} /** * * @Title: Printshortestpath * @Description: Print a->b Shortest path * @param @return settings file * @return iterable<integer> return Back type * @throws */public boolean printshortestpath (int a,int b) {if (Hasnegativecycle ()) {System.out.print ("has a negative weight ring, no shortest path exists" );} else if (a==b) System.out.println (A + "," +b), Else{system.out.print (A + ");p Ath (A, b); System.out.print (b);} return true;} private void Path (int a, int b) {int k=prev[a][b];if (k==-1) {return;} Path (A,K); System.out.print (k + ");p ath (k,b);} /** * * @Title: Addedge * @Description: Add edge * @param @param a * @param @param b * @param @param w settings file * @return void return class Type * @throws */public void Addedge (int a, int B, double w) {d[a][b] = W;} public static void Main (string[] args) {//Text data without negative weight ring string Text1 = "f:\\ algorithm \\attach\\tinyEWDn.txt";//Text data string containing negative weight ring Text2 = "f:\\ algorithm \\attach\\TinyEWDnc.txt ";" in. = New in (text1); int n = in.readint (); Floydwarshall f = new Floydwarshall (n), int e = In.readint (), for (int i = 0; i < e; i++) {F.addedge (In.readint (), In.rea DInt (), in.readdouble ());} F.findshortestpath (); int s = 0;for (int i = 0; i < n; i++) {System.out.println (S + "to" + i + "):" + F.distto (S, i)); F.printshortestpath (S, i); System.out.println ();}}}
If a negative weighted loop is used, an exception is thrown, indicating a negative ring and indicating no shortest path
If you use a graph that does not contain a negative ring, the following is printed (currently tested with S=0, and other points as the shortest path to the origin can be tried by itself):
Distances from 0 to 0 are: 0.00->00 to 1 Distance: 0.930->2->7->3->6->4->5->10 to 2 Distance: 0.260->20 to 3 is:0.990-> The distance from 2->7->30 to 4 is: 0.260->2->7->3->6->40 to 5 is:0.610->2->7->3->6->4-> The distance from 50 to 6 is: 1.510->2->7->3->60 to 7 is: 0.60->2->7
Introduction to algorithm--the shortest path of all point pairs: Floydwarshall algorithm