/// <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. }
/// <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. }