I. Overview
definition: In a weighted graph, the shortest path from vertex s to vertex T is the smallest of all weights in the path from S to T. From the definition, it can be seen that the realization of the single-point shortest path is based on the weighted graph.
Shortest path tree: Given a weighted graph and a vertex s, a shortest path tree starting with S is a sub-graph of the graph, which contains s and all vertices from S. The root node of the tree is s, and each path of the tree is a shortest path in the graph. It contains the shortest path of the vertex s to all the vertices that are reached .
Two. Weighted forward graphs and weighted forward-edged data structures
The data structures with weighted and weighted forward edges and weighted non-anisotropic graphs have the same structure type. The code is as follows:
//weighted forward-edged data types Public classDirectededge {Private Final intV//the beginning of the side Private Final intW//the end of the edge Private Final DoubleWeight//the weight of the edge PublicDirectededge (intVintWDoubleweight) { Super(); This. v =v; This. W =W; This. Weight =weight; } Public Doubleweight () {returnweight; } Public intFrom () {returnv; } Public intTo () {returnW; } }
Public classEdgeweighteddigraph {Private Final intV//Total vertices Private intE//total number of edges Privatebag<directededge> [] adj;//adjacency Table PublicEdgeweighteddigraph (intV) {Super(); This. V =V; This. E=0; Adj= (bag<directededge> [])NewBag[v]; for(intv=0;v<v;v++) {Adj[v]=NewBag<directededge>(); } } Public intV () {returnV;} Public intE () {returnE;} Public voidAddedge (Directededge e) {adj[e.from ()].add (e); E++; } //side indicated by v PublicIterable<directededge> Adj (intv) {returnAdj[v]; } PublicIterable<directededge>edges () {Bag<DirectedEdge> bag=NewBag<>(); for(intv=0;v<v;v++) { for(Directededge E:adj[v]) {Bag.add (e); } } returnbag; }}
Three. Relaxation (Relax method)
The relaxation of the edges is defined as follows: Relaxed edge v->w means that the shortest path from S to W is checked first from S to V, then v to W, and if so, the contents of the data structure are updated according to this condition. The shortest path from V to W is the sum of distto[v] and e.weight () If the value is not less than distto[w] it is said to be invalid and ignored, and if it is small, the data is updated. The slack operation is shown in the following code:
Private void Relax (Directededge e) { int v=e.from (); int w=e.to (); if (distto[w]>distto[v]+e.weight ()) { distto[w]=distto[v]+e.weight (); EDGETO[W]=e; } }
Vertex relaxation: For a vertex, relaxing it means relaxing the edges it points out. The code for the vertex's slack is as follows:
for (Directededge E:g.adj (v)) { int w=e.to (); if (distto[w]>distto[v]+e.weight ()) { distto[w]=distto[v]+e.weight (); EDGETO[W]=e; } }
Four. The theoretical basis of the shortest path algorithm
Optimal conditions for Shortest path: g is a weighted graph, vertex s is the starting point in G, and distto[] is an array indexed by vertices. The length of the path in G is saved (the path to the beginning s). For all vertices from S to v,distto[v] The value is the length of a path from S to V, For all vertices that are unreachable by S, the value is infinity. Only if the values satisfy Distto[w]<=distto[e]+e.weight () for any of the edges from V to W, in other words, when there are no valid edges, they are the length of the shortest path.
Five. Dijkstra algorithm
The algorithm solves the shortest path with the following ideas:
Assuming that V is accessible from the starting point, when V is relaxed, there must be distto[w]<=distto[v]+e.weight (). Because the inequality will always be established before the algorithm ends, Distto[w] will only become smaller. and Distto[v] will not change. (because the distto[] smallest vertex is selected at each step, it is not possible to make any distto[] less than the value of distto[v]. Therefore, when all the vertices from S can be added to the tree, the optimality condition of the shortest path is established, that is, the proposition P is established.
The code is as follows:
/*** Calculate Shortest Path * from vertex s to v shortest path, determine if there is, if there is, give the shortest path. * Basic idea: * Add S to INDEXMINPQ, then a relaxation operation for the neighboring points of S, * get the nearest distance from the starting point of s adjacent point distance, and draw the smallest distance from it, add the corresponding point * to the shortest path tree. And so on, until all points are added to the tree *@authorAdministrator **/ Public classdijkstrasp {Privatedirectededge[] Edgeto; Private Double[] Distto; PrivateIndexminpq<double>PQ; PublicDijkstrasp (Edgeweighteddigraph G,ints) {Edgeto=Newdirectededge[g.v ()]; Distto=New Double[G.V ()]; PQ=NewIndexminpq<>(G.V ()); for(intV=0;V<G.V (); v++) {Distto[v]=double.positive_infinity; } Distto[s]=0.0; Pq.insert (s),0.0); while(!Pq.isempty ()) {Relax (G,pq.delmin ()); } } Private voidRelax (Edgeweighteddigraph G,intv) { for(Directededge E:g.adj (v)) {intw=e.to (); if(distto[w]>distto[v]+e.weight ()) {Distto[w]=distto[v]+e.weight (); EDGETO[W]=e; if(Pq.contains (w)) Pq.changekey (W, distto[w]); ElsePq.insert (W, distto[w]); } } } Public BooleanHaspathto (intv) {returndistto[v]<double.positive_infinity; } Public DoubleDistto (intv) {returnDistto[v]; } PublicIterable<directededge> Pathto (intv) {if(!haspathto (v))return NULL; Stack<DirectedEdge> path=NewStack<>(); for(Directededge e=edgeto[v];e!=NULL; e=Edgeto[e.from ()]) {Path.push (e); } returnpath; }}
Six. The shortest path algorithm in the non-ring weighted graph
The steps of its algorithm are: first Distto[s] is initialized to 0, the other distto[] elements are initialized to infinity, and then each of the vertices is relaxed according to the extension order. That is, the single-point shortest path problem can be solved for the non-ring weighted graph.
The steps to prove are as follows: For any one side v->w, when V is relaxed, gets distto[w]<=distto[v]+e.weight (). The inequality is established before the algorithm ends. Because Distto[v] is unchanged ( Because all vertices are relaxed according to the order in which they are sorted, the algorithm will not process any side that points to V after the V is relaxed, and distto[w] will only become smaller, so the optimality condition is established, so this step can get the shortest path tree.
/**the shortest path algorithm using the extension-complement sort. The premise is that there is no ring and the weight is positive*/ Public classACYCLICSP {Privatedirectededge[] Edgeto; Private Double[] Distto; PublicACYCLICSP (Edgeweighteddigraph G,ints) {Edgeto=Newdirectededge[g.v ()]; Distto=New Double[G.V ()]; for(intV=0;V<G.V (); v++) {Distto[v]=double.positive_infinity; } Distto[s]=0.0; Topological top=Newtopological (G); for(intV:top.order ()) {Relax (G,V); } } Private voidRelax (Edgeweighteddigraph G,intv) { for(Edu.princeton.cs.algs4.DirectedEdge E:g.adj (v)) {intw=e.to (); if(distto[w]>distto[v]+e.weight ()) {Distto[w]=distto[v]+e.weight (); EDGETO[W]=e; } } } Public BooleanHaspathto (intv) {returndistto[v]<double.positive_infinity; } Public DoubleDistto (intv) {returnDistto[v]; } PublicIterable<directededge> Pathto (intv) {if(!haspathto (v))return NULL; Stack<DirectedEdge> path=NewStack<>(); for(Directededge e=edgeto[v];e!=NULL; e=Edgeto[e.from ()]) {Path.push (e); } returnpath; }}
Algorithm _ Shortest Path