+void MTPGraph::increase_distance_in_heap(Vertex *v) {
+ Vertex **c1, **c2, **h;
+ // There is some beauty in that
+ h = v->heap_slot;
+ while(c1 = _heap + 2 * (h - _heap + 1) - 1, c2 = c1 + 1,
+ (c1 < _heap + _heap_size && (*c1)->distance_from_source < (*h)->distance_from_source)
+ ||
+ (c2 < _heap + _heap_size && (*c2)->distance_from_source < (*h)->distance_from_source)
+ ) {
+ if(c1 < _heap + _heap_size &&
+ !(c2 < _heap + _heap_size && (*c2)->distance_from_source < (*c1)->distance_from_source)){
+ swap(*c1, *h);
+ swap((*c1)->heap_slot, (*h)->heap_slot);
+ h = c1;
+ } else {
+ swap(*c2, *h);
+ swap((*c2)->heap_slot, (*h)->heap_slot);
+ h = c2;
+ }
+ }
+}
+
+void MTPGraph::dp_distance_propagation() {
+ Vertex *v, *tv;
+ Edge *e;
+ scalar_t d;
+
+ for(int k = 0; k < _nb_vertices; k++) {
+ _vertices[k].distance_from_source = FLT_MAX;
+ _vertices[k].pred_edge_toward_source = 0;
+ }
+
+ _source->distance_from_source = 0;
+
+ for(int k = 0; k < _nb_vertices; k++) {
+ v = _dp_order[k];
+ for(e = v->leaving_edges; e; e = e->next_leaving_edge) {
+ d = v->distance_from_source + e->positivized_length;
+ tv = e->terminal_vertex;
+ if(d < tv->distance_from_source) {
+ tv->distance_from_source = d;
+ tv->pred_edge_toward_source = e;
+ decrease_distance_in_heap(tv);
+ }
+ }
+ }
+}
+
+// This method does not change the edge occupation. It only sets
+// properly, for every vertex, the fields distance_from_source and
+// pred_edge_toward_source.
+
+void MTPGraph::find_shortest_path() {
+ Vertex *v, *tv, **a, **b;
+ Edge *e;
+ scalar_t d;
+
+ for(int k = 0; k < _nb_vertices; k++) {
+ _vertices[k].distance_from_source = FLT_MAX;
+ _vertices[k].pred_edge_toward_source = 0;
+ }
+
+ _heap_size = _nb_vertices;
+ _source->distance_from_source = 0;
+ decrease_distance_in_heap(_source);
+
+ do {
+ // Get the closest to the source
+ v = _heap[0];
+
+ // Remove it from the heap (swap it with the last in the heap, and
+ // update the distance of that one)
+ _heap_size--;
+ a = _heap;
+ b = _heap + _heap_size;
+ swap(*a, *b); swap((*a)->heap_slot, (*b)->heap_slot);
+ increase_distance_in_heap(_heap[0]);
+
+ // Now update the neighbors of the currently closest to the source
+ for(e = v->leaving_edges; e; e = e->next_leaving_edge) {
+ d = v->distance_from_source + e->positivized_length;
+ tv = e->terminal_vertex;
+ if(d < tv->distance_from_source) {
+ ASSERT(tv->heap_slot - _heap < _heap_size);
+ tv->distance_from_source = d;
+ tv->pred_edge_toward_source = e;
+ decrease_distance_in_heap(tv);
+ }
+ }
+ } while(_heap_size > 0);
+}
+
+void MTPGraph::find_best_paths(scalar_t *lengths) {