/// <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> /// Creates a new pre-processor. /// </summary> /// <param name="target"></param> /// <param name="calculator"></param> /// <param name="witnessCalculator"></param> /// <param name="keepDirectNeighbours"></param> public CHPreProcessor(IDynamicGraphRouterDataSource<CHEdgeData> target, INodeWeightCalculator calculator, INodeWitnessCalculator witnessCalculator, bool keepDirectNeighbours, double preProcessingPercentage) { _comparer = new CHEdgeDataComparer(); _keepDirectNeighbours = keepDirectNeighbours; _target = target; _calculator = calculator; _witnessCalculator = witnessCalculator; _preProcessingPercentage = preProcessingPercentage; _queue = new CHPriorityQueue(); _contracted = new bool[1000]; }
/// <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(); #if !WINDOWS_PHONE System.Collections.Concurrent.ConcurrentBag<KeyValuePair<uint, float>> recalculated_weights = new System.Collections.Concurrent.ConcurrentBag<KeyValuePair<uint, float>>(); System.Threading.Tasks.Parallel.ForEach(_queue, vertex => { recalculated_weights.Add( new KeyValuePair<uint,float>(vertex, _calculator.Calculate(vertex))); }); #endif #if WINDOWS_PHONE 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))); } #endif 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; } } } //// keep going over the enumerator and check. //while (_all_nodes.MoveNext()) //{ // // get the next vertex. // uint next = _all_nodes.Current; // if (this.CanBeContracted(next)) // { // yes, this vertex can be contracted! // _queue.Remove(next); // return next; // } //} // 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> /// Creates a new pre-processor. /// </summary> /// <param name="target"></param> /// <param name="calculator"></param> /// <param name="witnessCalculator"></param> /// <param name="keepReverseEdges"></param> public CHPreProcessor(IDynamicGraphRouterDataSource<CHEdgeData> target, INodeWeightCalculator calculator, INodeWitnessCalculator witnessCalculator, bool keepReverseEdges) { _comparer = new CHEdgeDataComparer(); _target = target; _calculator = calculator; _witnessCalculator = witnessCalculator; _queue = new CHPriorityQueue(); _contracted = new bool[1000]; }
/// <summary> /// Creates a new pre-processor. /// </summary> /// <param name="target"></param> /// <param name="calculator"></param> /// <param name="witness_calculator"></param> /// <param name="max"></param> public CHPreProcessor(IDynamicGraph<CHEdgeData> target, INodeWeightCalculator calculator, INodeWitnessCalculator witness_calculator, int max) { _comparer = new CHEdgeDataComparer(); _target = target; _calculator = calculator; _witness_calculator = witness_calculator; _queue = new CHPriorityQueue(); _contracted = new bool[1000]; }