Пример #1
0
        /// <summary>
        /// Implements a very simple dykstra version.
        /// </summary>
        /// <param name="from"></param>
        /// <param name="to"></param>
        /// <param name="via"></param>
        /// <param name="max_weight"></param>
        /// <param name="max_settles"></param>
        /// <returns></returns>
        private float CalculateWeight(uint from, uint to, uint via, float max_weight, int max_settles)
        {
            int max_hops = 5;
            float weight = float.MaxValue;

            // creates the settled list.
            HashSet<uint> settled = new HashSet<uint>();
            settled.Add(via);

            // creates the priorty queue.
            BinairyHeap<SettledVertex> heap = new BinairyHeap<SettledVertex>();
            heap.Push(new SettledVertex(from, 0, 0), 0);

            // keep looping until the queue is empty or the target is found!
            while (heap.Count > 0)
            {
                // pop the first customer.
                SettledVertex current = heap.Pop();
                if (!settled.Contains(current.VertexId))
                { // the current vertex has net been settled.
                    settled.Add(current.VertexId); // settled the vertex.

                    // test stop conditions.
                    if (current.VertexId == to)
                    { // target is found!
                        return current.Weight;
                    }

                    // test the hop count.
                    if (current.Hops < max_hops)
                    { // the neighbours will only increase hops!
                        if (settled.Count >= max_settles)
                        { // do not continue searching.
                            return float.MaxValue;
                        }

                        // get the neighbours.
                        KeyValuePair<uint, CHEdgeData>[] neighbours = _data.GetArcs(current.VertexId);
                        for (int idx = 0; idx < neighbours.Length; idx++)
                        {
                            if (neighbours[idx].Value.Forward && (neighbours[idx].Key == to || !settled.Contains(neighbours[idx].Key)))
                            {
                                SettledVertex neighbour = new SettledVertex(neighbours[idx].Key,
                                    neighbours[idx].Value.Weight + current.Weight, current.Hops + 1);
                                if (neighbour.Weight < max_weight)
                                {
                                    if (neighbours[idx].Key == to)
                                    {
                                        return neighbour.Weight;
                                    }
                                    heap.Push(neighbour, neighbour.Weight);
                                }
                            }
                        }
                    }
                }
            }

            return weight;
        }
Пример #2
0
        /// <summary>
        /// Calculates witnesses from on source to multiple targets at once.
        /// </summary>
        /// <param name="graph"></param>
        /// <param name="from"></param>
        /// <param name="tos"></param>
        /// <param name="tosWeights"></param>
        /// <param name="maxSettles"></param>
        /// <param name="forwardExists"></param>
        /// <param name="backwardExists"></param>
        /// <param name="toSkip"></param>
        public void Exists(GraphBase<CHEdgeData> graph, uint from, List<uint> tos, List<float> tosWeights, int maxSettles,
            ref bool[] forwardExists, ref bool[] backwardExists, uint toSkip)
        {
            int maxHops = _hopLimit;

            if (maxHops == 1)
            {
                this.ExistsOneHop(graph, from, tos, tosWeights, maxSettles, ref forwardExists, ref backwardExists);
                return;
            }

            // creates the settled list.
            var backwardSettled = new HashSet<uint>();
            var forwardSettled = new HashSet<uint>();
            var backwardToSet = new HashSet<uint>();
            var forwardToSet = new HashSet<uint>();
            float forwardMaxWeight = 0, backwardMaxWeight = 0;
            for (int idx = 0; idx < tosWeights.Count; idx++)
            {
                if (!forwardExists[idx])
                {
                    forwardToSet.Add(tos[idx]);
                    if (forwardMaxWeight < tosWeights[idx])
                    {
                        forwardMaxWeight = tosWeights[idx];
                    }
                }
                if (!backwardExists[idx])
                {
                    backwardToSet.Add(tos[idx]);
                    if (backwardMaxWeight < tosWeights[idx])
                    {
                        backwardMaxWeight = tosWeights[idx];
                    }
                }
            }
            if (forwardMaxWeight == 0 && backwardMaxWeight == 0)
            { // no need to search!
                return;
            }

            // creates the priorty queue.
            var forwardMinWeight = new Dictionary<uint, float>();
            var backwardMinWeight = new Dictionary<uint, float>();
            var heap = _reusableHeap;
            heap.Clear();
            heap.Push(new SettledVertex(from, 0, 0, forwardMaxWeight > 0, backwardMaxWeight > 0), 0);

            // keep looping until the queue is empty or the target is found!
            while (heap.Count > 0)
            { // pop the first customer.
                var current = heap.Pop();
                if (current.Hops + 1 < maxHops)
                { // the current vertex has net been settled.
                    if(current.VertexId == toSkip)
                    {
                        continue;
                    }
                    bool forwardWasSettled = forwardSettled.Contains(current.VertexId);
                    bool backwardWasSettled = backwardSettled.Contains(current.VertexId);
                    if (forwardWasSettled && backwardWasSettled)
                    {
                        continue;
                    }

                    if (current.Forward)
                    { // this is a forward settle.
                        forwardSettled.Add(current.VertexId);
                        forwardMinWeight.Remove(current.VertexId);
                        if (forwardToSet.Contains(current.VertexId))
                        {
                            int index = tos.IndexOf(current.VertexId);
                            forwardExists[index] = current.Weight <= tosWeights[index];
                            //if (forwardExists[index])
                            //{
                            forwardToSet.Remove(current.VertexId);
                            //}
                        }
                    }
                    if (current.Backward)
                    { // this is a backward settle.
                        backwardSettled.Add(current.VertexId);
                        backwardMinWeight.Remove(current.VertexId);
                        if (backwardToSet.Contains(current.VertexId))
                        {
                            int index = tos.IndexOf(current.VertexId);
                            backwardExists[index] = current.Weight <= tosWeights[index];
                            //if (backwardExists[index])
                            //{
                            backwardToSet.Remove(current.VertexId);
                            //}
                        }
                    }

                    if (forwardToSet.Count == 0 &&
                        backwardToSet.Count == 0)
                    { // there is nothing left to check.
                        break;
                    }

                    if (forwardSettled.Count >= maxSettles &&
                        backwardSettled.Count >= maxSettles)
                    { // do not continue searching.
                        break;
                    }

                    bool doForward = current.Forward && forwardToSet.Count > 0 && !forwardWasSettled;
                    bool doBackward = current.Backward && backwardToSet.Count > 0 && !backwardWasSettled;
                    if (doForward || doBackward)
                    { // get the neighbours.
                        var neighbours = graph.GetEdges(current.VertexId);
                        while (neighbours.MoveNext())
                        { // move next.
                            var edgeData = neighbours.EdgeData;
                            var neighbourWeight = current.Weight + edgeData.Weight;
                            var doNeighbourForward = doForward && edgeData.CanMoveForward && neighbourWeight <= forwardMaxWeight &&
                                !forwardSettled.Contains(neighbours.Neighbour);
                            var doNeighbourBackward = doBackward && edgeData.CanMoveBackward && neighbourWeight <= backwardMaxWeight &&
                                !backwardSettled.Contains(neighbours.Neighbour);
                            if (doNeighbourBackward || doNeighbourForward)
                            {
                                float existingWeight;
                                if (doNeighbourForward)
                                {
                                    if (forwardMinWeight.TryGetValue(neighbours.Neighbour, out existingWeight))
                                    {
                                        if(existingWeight <= neighbourWeight)
                                        {
                                            doNeighbourForward = false;
                                        }
                                        else
                                        {
                                            forwardMinWeight[neighbours.Neighbour] = neighbourWeight;
                                        }
                                    }
                                    else
                                    {
                                        forwardMinWeight[neighbours.Neighbour] = neighbourWeight;
                                    }
                                }
                                if (doNeighbourBackward)
                                {
                                    if (backwardMinWeight.TryGetValue(neighbours.Neighbour, out existingWeight))
                                    {
                                        if (existingWeight <= neighbourWeight)
                                        {
                                            doNeighbourBackward = false;
                                        }
                                        else
                                        {
                                            backwardMinWeight[neighbours.Neighbour] = neighbourWeight;
                                        }
                                    }
                                    else
                                    {
                                        backwardMinWeight[neighbours.Neighbour] = neighbourWeight;
                                    }
                                }

                                if (doNeighbourBackward || doNeighbourForward)
                                {
                                    var neighbour = new SettledVertex(neighbours.Neighbour,
                                        neighbourWeight, current.Hops + 1, doNeighbourForward, doNeighbourBackward);
                                    heap.Push(neighbour, neighbour.Weight);
                                }
                            }
                        }
                    }
                }
            }
        }
Пример #3
0
        /// <summary>
        /// Implements a very simple dykstra version.
        /// </summary>
        /// <param name="graph"></param>
        /// <param name="from"></param>
        /// <param name="to"></param>
        /// <param name="via"></param>
        /// <param name="max_weight"></param>
        /// <param name="max_settles"></param>
        /// <returns></returns>
        private float CalculateWeight(IBasicRouterDataSource <CHEdgeData> graph, uint from, uint to, uint via, float max_weight, int max_settles)
        {
            int   max_hops = _hopLimit;
            float weight   = float.MaxValue;

            // creates the settled list.
            HashSet <uint> settled = new HashSet <uint>();

            settled.Add(via);

            // creates the priorty queue.
            BinairyHeap <SettledVertex> heap = new BinairyHeap <SettledVertex>();

            heap.Push(new SettledVertex(from, 0, 0), 0);

            // keep looping until the queue is empty or the target is found!
            while (heap.Count > 0)
            {
                // pop the first customer.
                SettledVertex current = heap.Pop();
                if (!settled.Contains(current.VertexId))
                {                                  // the current vertex has net been settled.
                    settled.Add(current.VertexId); // settled the vertex.

                    // test stop conditions.
                    if (current.VertexId == to)
                    { // target is found!
                        return(current.Weight);
                    }

                    // test the hop count.
                    if (current.Hops < max_hops)
                    {     // the neighbours will only increase hops!
                        if (settled.Count >= max_settles)
                        { // do not continue searching.
                            return(float.MaxValue);
                        }

                        // get the neighbours.
                        KeyValuePair <uint, CHEdgeData>[] neighbours = graph.GetEdges(current.VertexId);
                        for (int idx = 0; idx < neighbours.Length; idx++)
                        {
                            var neighbourPair = neighbours[idx];
                            if (neighbourPair.Value.Forward && (neighbourPair.Key == to || !settled.Contains(neighbourPair.Key)))
                            {
                                var neighbour = new SettledVertex(neighbours[idx].Key,
                                                                  neighbours[idx].Value.Weight + current.Weight, current.Hops + 1);
                                if (neighbour.Weight < max_weight)
                                {
                                    if (neighbours[idx].Key == to)
                                    {
                                        return(neighbour.Weight);
                                    }
                                    heap.Push(neighbour, neighbour.Weight);
                                }
                            }
                        }
                    }
                }
            }

            return(weight);
        }
Пример #4
0
        /// <summary>
        /// Calculates witness paths.
        /// </summary>
        public void Calculate(DirectedGraph graph, uint source, List <uint> targets, List <float> weights,
                              ref bool[] forwardWitness, ref bool[] backwardWitness, uint vertexToSkip)
        {
            if (_hopLimit == 1)
            {
                this.ExistsOneHop(graph, source, targets, weights, ref forwardWitness, ref backwardWitness);
                return;
            }

            // creates the settled list.
            var   backwardSettled = new HashSet <uint>();
            var   forwardSettled = new HashSet <uint>();
            var   backwardTargets = new HashSet <uint>();
            var   forwardTargets = new HashSet <uint>();
            float forwardMaxWeight = 0, backwardMaxWeight = 0;

            for (int idx = 0; idx < weights.Count; idx++)
            {
                if (!forwardWitness[idx])
                {
                    forwardTargets.Add(targets[idx]);
                    if (forwardMaxWeight < weights[idx])
                    {
                        forwardMaxWeight = weights[idx];
                    }
                }
                if (!backwardWitness[idx])
                {
                    backwardTargets.Add(targets[idx]);
                    if (backwardMaxWeight < weights[idx])
                    {
                        backwardMaxWeight = weights[idx];
                    }
                }
            }
            if (forwardMaxWeight == 0 && backwardMaxWeight == 0)
            { // no need to search!
                return;
            }

            // creates the priorty queue.
            var forwardMinWeight  = new Dictionary <uint, float>();
            var backwardMinWeight = new Dictionary <uint, float>();

            _heap.Clear();
            _heap.Push(new SettledVertex(source, 0, 0, forwardMaxWeight > 0, backwardMaxWeight > 0), 0);

            // keep looping until the queue is empty or the target is found!
            var edgeEnumerator = graph.GetEdgeEnumerator();

            while (_heap.Count > 0)
            { // pop the first customer.
                var current = _heap.Pop();
                if (current.Hops + 1 < _hopLimit)
                {
                    if (current.VertexId == vertexToSkip)
                    { // this is the vertex being contracted.
                        continue;
                    }
                    var forwardWasSettled  = forwardSettled.Contains(current.VertexId);
                    var backwardWasSettled = backwardSettled.Contains(current.VertexId);
                    if (forwardWasSettled && backwardWasSettled)
                    { // both are already settled.
                        continue;
                    }

                    if (current.Forward)
                    { // this is a forward settle.
                        forwardSettled.Add(current.VertexId);
                        forwardMinWeight.Remove(current.VertexId);
                        if (forwardTargets.Contains(current.VertexId))
                        {
                            for (var i = 0; i < targets.Count; i++)
                            {
                                if (targets[i] == current.VertexId)
                                {
                                    forwardWitness[i] = current.Weight < weights[i];
                                    forwardTargets.Remove(current.VertexId);
                                }
                            }
                        }
                    }
                    if (current.Backward)
                    { // this is a backward settle.
                        backwardSettled.Add(current.VertexId);
                        backwardMinWeight.Remove(current.VertexId);
                        if (backwardTargets.Contains(current.VertexId))
                        {
                            for (var i = 0; i < targets.Count; i++)
                            {
                                if (targets[i] == current.VertexId)
                                {
                                    backwardWitness[i] = current.Weight < weights[i];
                                    backwardTargets.Remove(current.VertexId);
                                }
                            }
                        }
                    }

                    if (forwardTargets.Count == 0 &&
                        backwardTargets.Count == 0)
                    { // there is nothing left to check.
                        break;
                    }

                    if (forwardSettled.Count >= _maxSettles &&
                        backwardSettled.Count >= _maxSettles)
                    { // do not continue searching.
                        break;
                    }

                    var doForward  = current.Forward && forwardTargets.Count > 0 && !forwardWasSettled;
                    var doBackward = current.Backward && backwardTargets.Count > 0 && !backwardWasSettled;
                    if (doForward || doBackward)
                    { // get the neighbours.
                        edgeEnumerator.MoveTo(current.VertexId);
                        while (edgeEnumerator.MoveNext())
                        { // move next.
                            var neighbour = edgeEnumerator.Neighbour;

                            float neighbourWeight;
                            bool? neighbourDirection;
                            ContractedEdgeDataSerializer.Deserialize(edgeEnumerator.Data0,
                                                                     out neighbourWeight, out neighbourDirection);
                            var neighbourCanMoveForward  = neighbourDirection == null || neighbourDirection.Value;
                            var neighbourCanMoveBackward = neighbourDirection == null || !neighbourDirection.Value;

                            var totalNeighbourWeight = current.Weight + neighbourWeight;
                            var doNeighbourForward   = doForward && neighbourCanMoveForward && totalNeighbourWeight < forwardMaxWeight &&
                                                       !forwardSettled.Contains(neighbour);
                            var doNeighbourBackward = doBackward && neighbourCanMoveBackward && totalNeighbourWeight < backwardMaxWeight &&
                                                      !backwardSettled.Contains(neighbour);
                            if (doNeighbourBackward || doNeighbourForward)
                            {
                                float existingWeight;
                                if (doNeighbourForward)
                                {
                                    if (forwardMinWeight.TryGetValue(neighbour, out existingWeight))
                                    {
                                        if (existingWeight <= totalNeighbourWeight)
                                        {
                                            doNeighbourForward = false;
                                        }
                                        else
                                        {
                                            forwardMinWeight[neighbour] = totalNeighbourWeight;
                                        }
                                    }
                                    else
                                    {
                                        forwardMinWeight[neighbour] = totalNeighbourWeight;
                                    }
                                }
                                if (doNeighbourBackward)
                                {
                                    if (backwardMinWeight.TryGetValue(neighbour, out existingWeight))
                                    {
                                        if (existingWeight <= totalNeighbourWeight)
                                        {
                                            doNeighbourBackward = false;
                                        }
                                        else
                                        {
                                            backwardMinWeight[neighbour] = totalNeighbourWeight;
                                        }
                                    }
                                    else
                                    {
                                        backwardMinWeight[neighbour] = totalNeighbourWeight;
                                    }
                                }

                                if (doNeighbourBackward || doNeighbourForward)
                                { // add to heap.
                                    var newSettle = new SettledVertex(neighbour,
                                                                      totalNeighbourWeight, current.Hops + 1, doNeighbourForward, doNeighbourBackward);
                                    _heap.Push(newSettle, newSettle.Weight);
                                }
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Calculates witnesses from on source to multiple targets at once.
        /// </summary>
        /// <param name="graph"></param>
        /// <param name="from"></param>
        /// <param name="tos"></param>
        /// <param name="tosWeights"></param>
        /// <param name="maxSettles"></param>
        /// <param name="forwardExists"></param>
        /// <param name="backwardExists"></param>
        /// <param name="toSkip"></param>
        public void Exists(GraphBase <CHEdgeData> graph, uint from, List <uint> tos, List <float> tosWeights, int maxSettles,
                           ref bool[] forwardExists, ref bool[] backwardExists, uint toSkip)
        {
            int maxHops = _hopLimit;

            if (maxHops == 1)
            {
                this.ExistsOneHop(graph, from, tos, tosWeights, maxSettles, ref forwardExists, ref backwardExists);
                return;
            }

            // creates the settled list.
            var   backwardSettled = new HashSet <uint>();
            var   forwardSettled = new HashSet <uint>();
            var   backwardToSet = new HashSet <uint>();
            var   forwardToSet = new HashSet <uint>();
            float forwardMaxWeight = 0, backwardMaxWeight = 0;

            for (int idx = 0; idx < tosWeights.Count; idx++)
            {
                if (!forwardExists[idx])
                {
                    forwardToSet.Add(tos[idx]);
                    if (forwardMaxWeight < tosWeights[idx])
                    {
                        forwardMaxWeight = tosWeights[idx];
                    }
                }
                if (!backwardExists[idx])
                {
                    backwardToSet.Add(tos[idx]);
                    if (backwardMaxWeight < tosWeights[idx])
                    {
                        backwardMaxWeight = tosWeights[idx];
                    }
                }
            }
            if (forwardMaxWeight == 0 && backwardMaxWeight == 0)
            { // no need to search!
                return;
            }

            // creates the priorty queue.
            var forwardMinWeight  = new Dictionary <uint, float>();
            var backwardMinWeight = new Dictionary <uint, float>();
            var heap = _reusableHeap;

            heap.Clear();
            heap.Push(new SettledVertex(from, 0, 0, forwardMaxWeight > 0, backwardMaxWeight > 0), 0);

            // keep looping until the queue is empty or the target is found!
            while (heap.Count > 0)
            { // pop the first customer.
                var current = heap.Pop();
                if (current.Hops + 1 < maxHops)
                { // the current vertex has net been settled.
                    if (current.VertexId == toSkip)
                    {
                        continue;
                    }
                    bool forwardWasSettled  = forwardSettled.Contains(current.VertexId);
                    bool backwardWasSettled = backwardSettled.Contains(current.VertexId);
                    if (forwardWasSettled && backwardWasSettled)
                    {
                        continue;
                    }

                    if (current.Forward)
                    { // this is a forward settle.
                        forwardSettled.Add(current.VertexId);
                        forwardMinWeight.Remove(current.VertexId);
                        if (forwardToSet.Contains(current.VertexId))
                        {
                            int index = tos.IndexOf(current.VertexId);
                            forwardExists[index] = current.Weight <= tosWeights[index];
                            //if (forwardExists[index])
                            //{
                            forwardToSet.Remove(current.VertexId);
                            //}
                        }
                    }
                    if (current.Backward)
                    { // this is a backward settle.
                        backwardSettled.Add(current.VertexId);
                        backwardMinWeight.Remove(current.VertexId);
                        if (backwardToSet.Contains(current.VertexId))
                        {
                            int index = tos.IndexOf(current.VertexId);
                            backwardExists[index] = current.Weight <= tosWeights[index];
                            //if (backwardExists[index])
                            //{
                            backwardToSet.Remove(current.VertexId);
                            //}
                        }
                    }

                    if (forwardToSet.Count == 0 &&
                        backwardToSet.Count == 0)
                    { // there is nothing left to check.
                        break;
                    }

                    if (forwardSettled.Count >= maxSettles &&
                        backwardSettled.Count >= maxSettles)
                    { // do not continue searching.
                        break;
                    }

                    bool doForward  = current.Forward && forwardToSet.Count > 0 && !forwardWasSettled;
                    bool doBackward = current.Backward && backwardToSet.Count > 0 && !backwardWasSettled;
                    if (doForward || doBackward)
                    { // get the neighbours.
                        var neighbours = graph.GetEdges(current.VertexId);
                        while (neighbours.MoveNext())
                        { // move next.
                            var edgeData           = neighbours.EdgeData;
                            var neighbourWeight    = current.Weight + edgeData.Weight;
                            var doNeighbourForward = doForward && edgeData.CanMoveForward && neighbourWeight <= forwardMaxWeight &&
                                                     !forwardSettled.Contains(neighbours.Neighbour);
                            var doNeighbourBackward = doBackward && edgeData.CanMoveBackward && neighbourWeight <= backwardMaxWeight &&
                                                      !backwardSettled.Contains(neighbours.Neighbour);
                            if (doNeighbourBackward || doNeighbourForward)
                            {
                                float existingWeight;
                                if (doNeighbourForward)
                                {
                                    if (forwardMinWeight.TryGetValue(neighbours.Neighbour, out existingWeight))
                                    {
                                        if (existingWeight <= neighbourWeight)
                                        {
                                            doNeighbourForward = false;
                                        }
                                        else
                                        {
                                            forwardMinWeight[neighbours.Neighbour] = neighbourWeight;
                                        }
                                    }
                                    else
                                    {
                                        forwardMinWeight[neighbours.Neighbour] = neighbourWeight;
                                    }
                                }
                                if (doNeighbourBackward)
                                {
                                    if (backwardMinWeight.TryGetValue(neighbours.Neighbour, out existingWeight))
                                    {
                                        if (existingWeight <= neighbourWeight)
                                        {
                                            doNeighbourBackward = false;
                                        }
                                        else
                                        {
                                            backwardMinWeight[neighbours.Neighbour] = neighbourWeight;
                                        }
                                    }
                                    else
                                    {
                                        backwardMinWeight[neighbours.Neighbour] = neighbourWeight;
                                    }
                                }

                                if (doNeighbourBackward || doNeighbourForward)
                                {
                                    var neighbour = new SettledVertex(neighbours.Neighbour,
                                                                      neighbourWeight, current.Hops + 1, doNeighbourForward, doNeighbourBackward);
                                    heap.Push(neighbour, neighbour.Weight);
                                }
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Calculates witnesses from on source to multiple targets at once.
        /// </summary>
        /// <param name="graph"></param>
        /// <param name="from"></param>
        /// <param name="tos"></param>
        /// <param name="tosWeights"></param>
        /// <param name="maxSettles"></param>
        /// <param name="exists"></param>
        public void Exists(IBasicRouterDataSource<CHEdgeData> graph, uint from, List<uint> tos, List<float> tosWeights, int maxSettles, ref bool[] exists)
        {
            int maxHops = _hopLimit;

            if (maxHops == 1)
            {
                this.ExistsOneHop(graph, from, tos, tosWeights, maxSettles, ref exists);
                return;
            }

            // creates the settled list.
            var settled = new HashSet<uint>();
            var toSet = new HashSet<uint>();
            float maxWeight = 0;
            for(int idx = 0; idx < tos.Count; idx++)
            {
                if(!exists[idx])
                {
                    toSet.Add(tos[idx]);
                    if(maxWeight < tosWeights[idx])
                    {
                        maxWeight = tosWeights[idx];
                    }
                }
            }

            // creates the priorty queue.
            var heap = _reusableHeap;
            heap.Clear();
            heap.Push(new SettledVertex(from, 0, 0), 0);

            // keep looping until the queue is empty or the target is found!
            while (heap.Count > 0)
            {
                // pop the first customer.
                var current = heap.Pop();
                if (!settled.Contains(current.VertexId))
                { // the current vertex has net been settled.
                    settled.Add(current.VertexId); // settled the vertex.

                    // check if this is a to.
                    if(toSet.Contains(current.VertexId))
                    {
                        int index = tos.IndexOf(current.VertexId);
                        exists[index] = current.Weight < tosWeights[index];
                        toSet.Remove(current.VertexId);

                        if(toSet.Count == 0)
                        {
                            break;
                        }
                    }

                    if (settled.Count >= maxSettles)
                    { // do not continue searching.
                        break;
                    }

                    // get the neighbours.
                    var neighbours = graph.GetEdges(current.VertexId);
                    while (neighbours.MoveNext())
                    {
                        if (!settled.Contains(neighbours.Neighbour))
                        {
                            if (neighbours.isInverted)
                            {
                                var invertedEdgeData = neighbours.InvertedEdgeData;
                                if (invertedEdgeData.Backward &&
                                    !invertedEdgeData.ToHigher &&
                                    !invertedEdgeData.ToLower)
                                {
                                    var neighbour = new SettledVertex(neighbours.Neighbour,
                                        invertedEdgeData.BackwardWeight + current.Weight, current.Hops + 1);
                                    if (neighbour.Weight < maxWeight && neighbour.Hops < maxHops)
                                    {
                                        heap.Push(neighbour, neighbour.Weight);
                                        //if (toSet.Contains(neighbours.Neighbour)) // check early for witnesses.
                                        //{ // this neighbour has been found and it already represents a witness even if not shortest.
                                        //    int index = tos.IndexOf(neighbours.Neighbour);
                                        //    if (neighbour.Weight < tosWeights[index] ||
                                        //        heap.Peek().VertexId == neighbours.Neighbour)
                                        //    { // ok, witness already found.
                                        //        exists[index] = current.Weight < tosWeights[index];
                                        //        toSet.Remove(neighbours.Neighbour);

                                        //        if (toSet.Count == 0)
                                        //        {
                                        //            break;
                                        //        }
                                        //    }
                                        //}
                                    }
                                }
                            }
                            else
                            {
                                var edgeData = neighbours.EdgeData;
                                if (edgeData.Forward &&
                                    !edgeData.ToHigher &&
                                    !edgeData.ToLower)
                                {
                                    var neighbour = new SettledVertex(neighbours.Neighbour,
                                        edgeData.ForwardWeight + current.Weight, current.Hops + 1);
                                    if (neighbour.Weight < maxWeight && neighbour.Hops < maxHops)
                                    {
                                        heap.Push(neighbour, neighbour.Weight);
                                        //if (toSet.Contains(neighbours.Neighbour)) // check early for witnesses.
                                        //{ // this neighbour has been found and it already represents a witness even if not shortest.
                                        //    int index = tos.IndexOf(neighbours.Neighbour);
                                        //    if (neighbour.Weight < tosWeights[index] ||
                                        //        heap.Peek().VertexId == neighbours.Neighbour)
                                        //    { // ok, witness already found.
                                        //        exists[index] = current.Weight < tosWeights[index];
                                        //        toSet.Remove(neighbours.Neighbour);

                                        //        if (toSet.Count == 0)
                                        //        {
                                        //            break;
                                        //        }
                                        //    }
                                        //}
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }