/// <summary> /// Computes a shortest paths tree from the specified sourceVertex to every other vertex in the edge-weighted directed graph /// </summary> /// <param name="graph">The edge-weighted directed graph</param> /// <param name="sourceVertex">The source vertex to compute the shortest paths tree from</param> /// <exception cref="ArgumentOutOfRangeException">Throws an ArgumentOutOfRangeException if an edge weight is negative</exception> /// <exception cref="ArgumentNullException">Thrown if EdgeWeightedDigraph is null</exception> public DijkstraShortestPath(EdgeWeightedDigraph graph, int sourceVertex) { if (graph == null) { throw new ArgumentNullException("graph", "EdgeWeightedDigraph cannot be null"); } foreach (DirectedEdge edge in graph.Edges()) { if (edge.Weight < 0) { throw new ArgumentOutOfRangeException(string.Format("Edge: '{0}' has negative weight", edge)); } } _distanceTo = new double[graph.NumberOfVertices]; _edgeTo = new DirectedEdge[graph.NumberOfVertices]; for (int v = 0; v < graph.NumberOfVertices; v++) { _distanceTo[v] = double.PositiveInfinity; } _distanceTo[sourceVertex] = 0.0; _priorityQueue = new IndexMinPriorityQueue <double>(graph.NumberOfVertices); _priorityQueue.Insert(sourceVertex, _distanceTo[sourceVertex]); while (!_priorityQueue.IsEmpty()) { int v = _priorityQueue.DeleteMin(); foreach (DirectedEdge edge in graph.Adjacent(v)) { Relax(edge); } } }
public void Initialize() { if (m_graph != null) { return; } List <Tuple <Tuple <uint, uint>, uint> > edges = new List <Tuple <Tuple <uint, uint>, uint> >(); // Initialize here foreach (TaxiPathRecord path in CliDB.TaxiPathStorage.Values) { TaxiNodesRecord from = CliDB.TaxiNodesStorage.LookupByKey(path.FromTaxiNode); TaxiNodesRecord to = CliDB.TaxiNodesStorage.LookupByKey(path.ToTaxiNode); if (from != null && to != null && from.Flags.HasAnyFlag(TaxiNodeFlags.Alliance | TaxiNodeFlags.Horde) && to.Flags.HasAnyFlag(TaxiNodeFlags.Alliance | TaxiNodeFlags.Horde)) { AddVerticeAndEdgeFromNodeInfo(from, to, path.Id, edges); } } // create graph m_graph = new EdgeWeightedDigraph(m_nodesByVertex.Count); for (int j = 0; j < edges.Count; ++j) { m_graph.AddEdge(new DirectedEdge(edges[j].Item1.Item1, edges[j].Item1.Item2, edges[j].Item2)); } }
// TODO: This method should be private and should be called from the bottom of the constructor /// <summary> /// check optimality conditions: /// </summary> /// <param name="graph">The edge-weighted directed graph</param> /// <param name="sourceVertex">The source vertex to check optimality conditions from</param> /// <returns>True if all optimality conditions are met, false otherwise</returns> /// <exception cref="ArgumentNullException">Thrown on null EdgeWeightedDigraph</exception> public bool Check(EdgeWeightedDigraph graph, int sourceVertex) { if (graph == null) { throw new ArgumentNullException("graph", "EdgeWeightedDigraph cannot be null"); } if (_distanceTo[sourceVertex] != 0.0 || _edgeTo[sourceVertex] != null) { return(false); } for (int v = 0; v < graph.NumberOfVertices; v++) { if (v == sourceVertex) { continue; } if (_edgeTo[v] == null && _distanceTo[v] != double.PositiveInfinity) { return(false); } } for (int v = 0; v < graph.NumberOfVertices; v++) { foreach (DirectedEdge edge in graph.Adjacent(v)) { uint w = edge.To; if (_distanceTo[v] + edge.Weight < _distanceTo[w]) { return(false); } } } for (int w = 0; w < graph.NumberOfVertices; w++) { if (_edgeTo[w] == null) { continue; } DirectedEdge edge = _edgeTo[w]; uint v = edge.From; if (w != edge.To) { return(false); } if (_distanceTo[v] + edge.Weight != _distanceTo[w]) { return(false); } } return(true); }