// pred_edge_toward_source.
void MTPGraph::find_shortest_path() {
+ int heap_size;
Vertex *v, *tv, **last_slot;
Edge *e;
scalar_t d;
_vertices[k].pred_edge_toward_source = 0;
}
- int heap_size = _nb_vertices;
+ heap_size = _nb_vertices;
_source->distance_from_source = 0;
_source->decrease_distance_in_heap(_heap);
- while(heap_size > 0) {
+ while(heap_size > 1) {
// Get the closest to the source
v = _heap[0];
heap_size--;
last_slot = _heap + heap_size;
swap(*_heap, *last_slot); swap((*_heap)->heap_slot, (*last_slot)->heap_slot);
- _heap[0]->increase_distance_in_heap(_heap, last_slot);
+ (*_heap)->increase_distance_in_heap(_heap, last_slot);
// Now update the neighbors of the node currently closest to the
// source
//////////////////////////////////////////////////////////////////////
-static int compare_vertices_on_distance(const void *v1, const void *v2) {
- scalar_t delta =
- (*((Vertex **) v1))->distance_from_source -
- (*((Vertex **) v2))->distance_from_source;
- if(delta < 0) return -1;
- else if(delta > 0) return 1;
- else return 0;
-}
-
void MTPGraph::compute_dp_ordering() {
Vertex *v;
Edge *e;
int ntv;
- // This method computes for each node the length of the longest link
- // from the source, and orders the node in _dp_order according to
- // it. It aborts if the graph is not a DAG.
+ // This method orders the nodes by putting first the ones with no
+ // predecessors, then going on adding nodes whose predecessors have
+ // all been already added. Computing the distances from the source
+ // by visiting nodes in that order is equivalent to DP.
int *nb_predecessors = new int[_nb_vertices];
}
}
- scalar_t rank = 1;
while(already_processed < front) {
+ // Here, nodes before already_processed can be ignored, nodes
+ // before front were set to 0 predecessors during the previous
+ // iteration. During this new iteration, we have to visit the
+ // successors of these ones only, since they are the only ones
+ // which may end up with no predecessors.
new_front = front;
while(already_processed < front) {
v = *(already_processed++);
- v->distance_from_source = rank;
for(e = v->leaving_edge_list_root; e; e = e->next_leaving_edge) {
ntv = int(e->terminal_vertex - _vertices);
nb_predecessors[ntv]--;
}
}
front = new_front;
- rank++;
}
if(already_processed < _dp_order + _nb_vertices) {
}
delete[] nb_predecessors;
-
- for(int v = 0; v < _nb_vertices; v++) { _dp_order[v] = &_vertices[v]; }
- qsort(_dp_order, _nb_vertices, sizeof(Vertex *), compare_vertices_on_distance);
}
//////////////////////////////////////////////////////////////////////