Exemplo n.º 1
0
        /// <summary>
        /// Select the next vertex from the queue.
        /// </summary>
        /// <returns></returns>
        private uint?SelectNext()
        {
            // first check the first of the current queue.
            while (_queue.Count > 0)
            { // get the first vertex and check.
                // TODO: peek and get the weight at the same time.
                uint first_queued = _queue.Peek();

                // the lazy updating part!
                // calculate priority
                float priority         = _calculator.Calculate(first_queued);
                float current_priority = _queue.Weight(first_queued);
                if (priority != current_priority)
                { // a succesfull update.
                    _misses_queue.Enqueue(true);
                    _misses++;
                }
                else
                { // an unsuccessfull update.
                    _misses_queue.Enqueue(false);
                }
                if (_misses_queue.Count > _k)
                { // dequeue and update the misses.
                    if (_misses_queue.Dequeue())
                    {
                        _misses--;
                    }
                }

                // if the misses are _k
                if (_misses == _k)
                { // recalculation.
                    CHPriorityQueue new_queue = new CHPriorityQueue();

                    HashSet <KeyValuePair <uint, float> > recalculated_weights =
                        new HashSet <KeyValuePair <uint, float> >();
                    foreach (uint vertex in _queue)
                    {
                        recalculated_weights.Add(
                            new KeyValuePair <uint, float>(vertex, _calculator.Calculate(vertex)));
                    }
                    foreach (KeyValuePair <uint, float> pair in recalculated_weights)
                    {
                        new_queue.Enqueue(pair.Key, pair.Value);
                    }
                    _queue = new_queue;
                    _misses_queue.Clear();
                    _misses = 0;
                }
                else
                {     // no recalculation.
                    if (priority > current_priority)
                    { // re-enqueue the weight.
                        _queue.Enqueue(first_queued, priority);
                    }
                    else
                    {
                        //if (this.CanBeContracted(first_queued))
                        //{ // yet, this vertex can be contracted!
                        _queue.Remove(first_queued);
                        return(first_queued);
                    }
                }
            }

            // check the queue.
            if (_queue.Count > 0)
            {
                throw new Exception("Unqueued items left!, CanBeContracted is too restrictive!");
            }
            return(null); // all nodes have been contracted.
        }
Exemplo n.º 2
0
        /// <summary>
        /// Select the next vertex from the queue.
        /// </summary>
        /// <returns></returns>
        private uint?SelectNext()
        {
            // first check the first of the current queue.
            while (_queue.Count > 0)
            { // get the first vertex and check.
                // TODO: peek and get the weight at the same time.
                uint first_queued = _queue.Peek();

                // the lazy updating part!
                // calculate priority
                float priority         = _calculator.Calculate(first_queued);
                float current_priority = _queue.Weight(first_queued);
                if (priority != current_priority)
                { // a succesfull update.
                    _missesQueue.Enqueue(true);
                    _misses++;
                }
                else
                { // an unsuccessfull update.
                    _missesQueue.Enqueue(false);
                }
                if (_missesQueue.Count > _k)
                { // dequeue and update the misses.
                    if (_missesQueue.Dequeue())
                    {
                        _misses--;
                    }
                }

                // if the misses are _k
                if (_misses == _k)
                { // recalculation.
                    OsmSharp.Logging.Log.TraceEvent("CHPreProcessor", TraceEventType.Information,
                                                    "Recalculating queue...");

                    CHPriorityQueue new_queue = new CHPriorityQueue();

                    HashSet <KeyValuePair <uint, float> > recalculated_weights =
                        new HashSet <KeyValuePair <uint, float> >();
                    int totalCadinality = 0;
                    foreach (uint vertex in _queue)
                    {
                        recalculated_weights.Add(
                            new KeyValuePair <uint, float>(vertex, _calculator.Calculate(vertex)));
                        var arcs = _target.GetEdges(vertex);
                        if (arcs != null)
                        {
                            totalCadinality = arcs.Length + totalCadinality;
                        }
                    }
                    foreach (KeyValuePair <uint, float> pair in recalculated_weights)
                    {
                        new_queue.Enqueue(pair.Key, pair.Value);
                    }
                    OsmSharp.Logging.Log.TraceEvent("CHPreProcessor", TraceEventType.Information,
                                                    "Average card: {0}", (double)totalCadinality / (double)recalculated_weights.Count);
                    _queue = new_queue;
                    _missesQueue.Clear();
                    _misses = 0;
                }
                else
                {     // no recalculation.
                    if (priority > current_priority)
                    { // re-enqueue the weight.
                        _queue.Enqueue(first_queued, priority);
                    }
                    else
                    {
                        //if (this.CanBeContracted(first_queued))
                        //{ // yet, this vertex can be contracted!
                        _queue.Remove(first_queued);
                        return(first_queued);
                    }
                }
            }

            // check the queue.
            if (_queue.Count > 0)
            {
                throw new Exception("Unqueued items left!, CanBeContracted is too restrictive!");
            }
            return(null); // all nodes have been contracted.
        }