/// <summary> /// Initializes and resets. /// </summary> public void Initialize() { // algorithm always succeeds, it may be dealing with an empty network and there are no targets. this.HasSucceeded = true; // intialize dykstra data structures. _visits = new HashSet <uint>(); _pointerHeap = new BinaryHeap <uint>(); _pathTree = new PathTree(); // initialize the edge enumerator. _edgeEnumerator = _graph.GetEdgeEnumerator(); // queue source. if (!_source.Edge1.IsNoEdge) { _pointerHeap.Push(_weightHandler.AddPathTree(_pathTree, _source.Edge1.Raw, _source.Weight1, uint.MaxValue), 0); } if (!_source.Edge2.IsNoEdge) { _pointerHeap.Push(_weightHandler.AddPathTree(_pathTree, _source.Edge2.Raw, _source.Weight2, uint.MaxValue), 0); } }
/// <summary> /// Initializes and resets. /// </summary> public void Initialize() { // algorithm always succeeds, it may be dealing with an empty network and there are no targets. this.HasSucceeded = true; // intialize dykstra data structures. _pointerHeap = new BinaryHeap <uint>(); _pathTree = new PathTree(); _visited = new HashSet <uint>(); // queue source. if (_source.Vertex1 != Constants.NO_VERTEX) { _pointerHeap.Push(_weightHandler.AddPathTree(_pathTree, _source.Vertex1, _source.Weight1, uint.MaxValue), 0); } if (_source.Vertex2 != Constants.NO_VERTEX) { _pointerHeap.Push(_weightHandler.AddPathTree(_pathTree, _source.Vertex2, _source.Weight2, uint.MaxValue), 0); } // gets the edge enumerator. _edgeEnumerator = _graph.GetEdgeEnumerator(); }
/// <summary> /// Executes the actual run. /// </summary> protected override void DoRun(CancellationToken cancellationToken) { // keep settled vertices. _pathTree = new PathTree(); // initialize the queues. var forwardQueue = new BinaryHeap <uint>(); var backwardQueue = new BinaryHeap <uint>(); // queue sources. if (_source.Vertex1 != Constants.NO_VERTEX) { forwardQueue.Push(_weightHandler.AddPathTree(_pathTree, _source.Vertex1, _source.Weight1, uint.MaxValue), 0); } if (_source.Vertex2 != Constants.NO_VERTEX) { forwardQueue.Push(_weightHandler.AddPathTree(_pathTree, _source.Vertex2, _source.Weight2, uint.MaxValue), 0); } // queue targets. if (_target.Vertex1 != Constants.NO_VERTEX) { backwardQueue.Push(_weightHandler.AddPathTree(_pathTree, _target.Vertex1, _target.Weight1, uint.MaxValue), 0); } if (_target.Vertex2 != Constants.NO_VERTEX) { backwardQueue.Push(_weightHandler.AddPathTree(_pathTree, _target.Vertex2, _target.Weight2, uint.MaxValue), 0); } // update best with current visits. _best = new Tuple <uint, uint, T>(uint.MaxValue, uint.MaxValue, _weightHandler.Infinite); // calculate stopping conditions. var queueBackwardWeight = backwardQueue.PeekWeight(); var queueForwardWeight = forwardQueue.PeekWeight(); while (true) { // keep looping until stopping conditions. if (backwardQueue.Count == 0 && forwardQueue.Count == 0) { // stop the search; both queues are empty. break; } var bestItem2 = _weightHandler.GetMetric(_best.Item3); if (bestItem2 < queueForwardWeight && bestItem2 < queueBackwardWeight) { // stop the search: it now became impossible to find a shorter route by further searching. break; } // do a forward search. if (forwardQueue.Count > 0) { // first check for better path. // get the current queued with the smallest weight that hasn't been visited yet. var cPointer = forwardQueue.Pop(); uint cVertex, cPreviousPointer; T cWeight; _weightHandler.GetPathTree(_pathTree, cPointer, out cVertex, out cWeight, out cPreviousPointer); while (_forwardVisits.ContainsKey(cVertex)) { // keep trying. if (forwardQueue.Count == 0) { cPointer = uint.MaxValue; } else { cPointer = forwardQueue.Pop(); _weightHandler.GetPathTree(_pathTree, cPointer, out cVertex, out cWeight, out cPreviousPointer); } } if (cPointer != uint.MaxValue) { uint bPointer; if (_backwardVisits.TryGetValue(cVertex, out bPointer)) { // check for a new best. uint bVertex, bPreviousPointer; T bWeight; _weightHandler.GetPathTree(_pathTree, bPointer, out bVertex, out bWeight, out bPreviousPointer); var total = _weightHandler.Add(cWeight, bWeight); if (_weightHandler.IsSmallerThan(total, _best.Item2)) { // a better path was found. _best = new Tuple <uint, uint, T>(cPointer, bPointer, total); this.HasSucceeded = true; } } this.SearchForward(forwardQueue, cPointer, cVertex, cWeight); } } // do a backward search. if (backwardQueue.Count > 0) {// first check for better path. // get the current queued with the smallest weight that hasn't been visited yet. var cPointer = backwardQueue.Pop(); uint cVertex, cPreviousPointer; T cWeight; _weightHandler.GetPathTree(_pathTree, cPointer, out cVertex, out cWeight, out cPreviousPointer); while (_backwardVisits.ContainsKey(cVertex)) { // keep trying. if (backwardQueue.Count == 0) { cPointer = uint.MaxValue; } else { cPointer = backwardQueue.Pop(); _weightHandler.GetPathTree(_pathTree, cPointer, out cVertex, out cWeight, out cPreviousPointer); } } if (cPointer != uint.MaxValue) { uint bPointer; // best pointer. if (_forwardVisits.TryGetValue(cVertex, out bPointer)) { // check for a new best. uint bVertex, bPreviousPointer; T bWeight; _weightHandler.GetPathTree(_pathTree, bPointer, out bVertex, out bWeight, out bPreviousPointer); var total = _weightHandler.Add(cWeight, bWeight); if (_weightHandler.IsSmallerThan(total, _best.Item2)) { // a better path was found. _best = new Tuple <uint, uint, T>(bPointer, cPointer, total); this.HasSucceeded = true; } } this.SearchBackward(backwardQueue, cPointer, cVertex, cWeight); } } // calculate stopping conditions. if (forwardQueue.Count > 0) { queueForwardWeight = forwardQueue.PeekWeight(); } if (backwardQueue.Count > 0) { queueBackwardWeight = backwardQueue.PeekWeight(); } } }