private IndexMinPQ <double> pq; // priority queue of vertices /// <summary>Computes a shortest-paths tree from the source vertex <c>s</c> to every other /// vertex in the edge-weighted digraph <c>G</c>.</summary> /// <param name="G">the edge-weighted digraph</param> /// <param name="s">the source vertex</param> /// <exception cref="ArgumentException">if an edge weight is negative</exception> /// <exception cref="ArgumentException">unless 0 <= <c>s</c> <=e <c>V</c> - 1</exception> /// public DijkstraSP(EdgeWeightedDigraph G, int s) { foreach (DirectedEdge e in G.Edges()) { if (e.Weight < 0) { throw new ArgumentException("edge " + e + " has negative weight"); } } distTo = new double[G.V]; edgeTo = new DirectedEdge[G.V]; for (int v = 0; v < G.V; v++) { distTo[v] = double.PositiveInfinity; } distTo[s] = 0.0; // relax vertices in order of distance from s pq = new IndexMinPQ <double>(G.V); pq.Insert(s, distTo[s]); while (!pq.IsEmpty) { int v = pq.DelMin(); foreach (DirectedEdge e in G.Adj(v)) { relax(e); } } // check optimality conditions Debug.Assert(check(G, s)); }
// check optimality conditions: // (i) for all edges e: distTo[e.To] <= distTo[e.From] + e.Weight // (ii) for all edge e on the SPT: distTo[e.To] == distTo[e.From] + e.Weight private bool check(EdgeWeightedDigraph G, int s) { // check that edge weights are nonnegative foreach (DirectedEdge e in G.Edges()) { if (e.Weight < 0) { Console.Error.WriteLine("negative edge weight detected"); return(false); } } // check that distTo[v] and edgeTo[v] are consistent if (distTo[s] != 0.0 || edgeTo[s] != null) { Console.Error.WriteLine("distTo[s] and edgeTo[s] inconsistent"); return(false); } for (int v = 0; v < G.V; v++) { if (v == s) { continue; } if (edgeTo[v] == null && distTo[v] != double.PositiveInfinity) { Console.Error.WriteLine("distTo[] and edgeTo[] inconsistent"); return(false); } } // check that all edges e = v->w satisfy distTo[w] <= distTo[v] + e.weight() for (int v = 0; v < G.V; v++) { foreach (DirectedEdge e in G.Adj(v)) { int w = e.To; if (distTo[v] + e.Weight < distTo[w]) { Console.Error.WriteLine("edge " + e + " not relaxed"); return(false); } } } // check that all edges e = v->w on SPT satisfy distTo[w] == distTo[v] + e.weight() for (int w = 0; w < G.V; w++) { if (edgeTo[w] == null) { continue; } DirectedEdge e = edgeTo[w]; int v = e.From; if (w != e.To) { return(false); } if (distTo[v] + e.Weight != distTo[w]) { Console.Error.WriteLine("edge " + e + " on shortest path not tight"); return(false); } } return(true); }