Beispiel #1
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.
            _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);
            }
        }
Beispiel #2
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();
        }
Beispiel #3
0
        /// <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();
                }
            }
        }