/// <summary> /// Single-source weighted shortest-path algorithm. /// The Dijkstra algorithm is not used by Labyrinth but was included in the /// previous code and has been updated to use a custom priority queue. /// /// This code conversion is untested. /// </summary> /// <param name="startName">the integer name of the starting Vertex</param> public void Dijkstra(T startName) { PriorityQueue <SearchPath <T> > pq = new PriorityQueue <SearchPath <T> >( ); if (!vertexMap.ContainsKey(startName)) { throw new Exception("Start not found!"); } Vertex <T> start = vertexMap[startName]; if (start == null) { throw new Exception("Start vertex not found"); } ClearAll( ); pq.Enqueue(new SearchPath <T>(start, 0)); start.dist = 0; int nodesSeen = 0; while (!pq.IsEmpty && nodesSeen < vertexMap.Count) { SearchPath <T> vrec = pq.Dequeue(); Vertex <T> v = vrec.dest; if (v.scratch != 0) // already processed v { continue; } v.scratch = 1; nodesSeen++; foreach (Edge <T> e in v.adj) { Vertex <T> w = e.dest; double cvw = e.cost; if (cvw < 0) { throw new Exception("Graph has negative edges"); } if (w.dist > v.dist + cvw) { w.dist = v.dist + cvw; w.prev = v; pq.Enqueue(new SearchPath <T>(w, w.dist)); } } } }
/// <summary> /// CompareTo is required for the implementation of IComparable. /// It allows comparing one SearchPath with another based on cost. /// </summary> /// <param name="rhs">the right hand side SearchPath</param> /// <returns>-1 for lesser cost, 0 for same, or 1 for greater cost</returns> public int CompareTo(SearchPath <T> rhs) { double otherCost = rhs.cost; return(cost <otherCost ? -1 : cost> otherCost ? 1 : 0); }