class Vertex {
public:
int id;
- // These are the leaving edges
+
Edge *first_edge;
- scalar_t distance;
+ scalar_t distance_from_source;
Vertex *pred_vertex;
Edge *pred_edge;
Vertex() { first_edge = 0; }
inline void add_edge(Edge *e) {
- if(first_edge) { first_edge->pred = e; }
e->next = first_edge;
e->pred = 0;
+ if(first_edge) { first_edge->pred = e; }
first_edge = e;
}
};
class Graph {
-public:
+ void initialize_work_lengths();
+ void update_work_length();
+ void find_shortest_path(Vertex **front, Vertex **new_front);
+
int nb_vertices;
Edge *edge_heap;
Vertex *vertices;
Vertex *source, *sink;
+public:
Graph(int nb_vertices, int nb_edges, int *from, int *to, scalar_t *lengths,
int source, int sink);
+
~Graph();
- void initialize_work_lengths();
- void update_work_length();
- void find_shortest_path();
void find_best_paths();
void print();
void print_occupied_edges();
+ void dot_print();
};
void Graph::print() {
}
}
+void Graph::dot_print() {
+ cout << "digraph {" << endl;
+ cout << " node[shape=circle];" << endl;
+ for(int n = 0; n < nb_vertices; n++) {
+ for(Edge *e = vertices[n].first_edge; e; e = e->next) {
+ int a = n, b = e->terminal_vertex->id;
+ if(e->occupied) {
+ int c = a; a = b; b = c;
+ cout << " " << a << " -> " << b << " [style=bold,color=black,label=\"" << -e->length << "\"];" << endl;
+ } else {
+ cout << " " << a << " -> " << b << " [color=gray,label=\"" << e->length << "\"];" << endl;
+ }
+ }
+ }
+ cout << "}" << endl;
+}
+
Graph::Graph(int nb_vrt, int nb_edges,
int *from, int *to, scalar_t *lengths,
int src, int snk) {
void Graph::update_work_length() {
for(int n = 0; n < nb_vertices; n++) {
- scalar_t d = vertices[n].distance;
+ scalar_t d = vertices[n].distance_from_source;
for(Edge *e = vertices[n].first_edge; e; e = e->next) {
- e->work_length += d - e->terminal_vertex->distance;
+ e->work_length += d - e->terminal_vertex->distance_from_source;
}
}
}
-void Graph::find_shortest_path() {
- Vertex **front = new Vertex *[nb_vertices];
- Vertex **new_front = new Vertex *[nb_vertices];
+void Graph::find_shortest_path(Vertex **front, Vertex **new_front) {
Vertex **tmp_front;
int tmp_front_size;
Vertex *v, *tv;
#endif
for(int v = 0; v < nb_vertices; v++) {
- vertices[v].distance = FLT_MAX;
+ vertices[v].distance_from_source = FLT_MAX;
vertices[v].pred_vertex = 0;
vertices[v].pred_edge = 0;
}
int front_size = 0, new_front_size;
front[front_size++] = source;
- source->distance = 0;
+ source->distance_from_source = 0;
do {
new_front_size = 0;
for(int f = 0; f < front_size; f++) {
v = front[f];
for(Edge *e = v->first_edge; e; e = e->next) {
- d = v->distance + e->work_length;
+ d = v->distance_from_source + e->work_length;
tv = e->terminal_vertex;
- if(d < tv->distance) {
- tv->distance = d;
+ if(d < tv->distance_from_source) {
+ tv->distance_from_source = d;
tv->pred_vertex = v;
tv->pred_edge = e;
new_front[new_front_size++] = tv;
new_front_size = front_size;
front_size = tmp_front_size;
} while(front_size > 0);
-
- delete[] front;
- delete[] new_front;
}
void Graph::find_best_paths() {
+ Vertex **front = new Vertex *[nb_vertices];
+ Vertex **new_front = new Vertex *[nb_vertices];
+
scalar_t total_length;
initialize_work_lengths();
do {
-#ifdef VERBOSE
- print();
-#endif
-
total_length = 0.0;
- find_shortest_path();
+ find_shortest_path(front, new_front);
update_work_length();
// Do we reach the sink?
if(sink->pred_edge) {
-#ifdef VERBOSE
- cout << "VERBOSE there is a path reaching the sink" << endl;
-#endif
-
// If yes, compute the length of the best path
for(Vertex *v = sink; v->pred_edge; v = v->pred_vertex) {
total_length += v->pred_edge->length;
}
-#ifdef VERBOSE
- cout << "VERBOSE total_length " << total_length << endl;
-#endif
-
// If that length is negative
if(total_length < 0.0) {
// Invert all the edges along the best path
}
}
} while(total_length < 0.0);
+
+ // // We put all occupied edges back to their original orientations
+ // for(int n = 0; n < nb_vertices; n++) {
+ // Vertex *v = &vertices[n];
+ // for(Edge *e = v->first_edge; e; e = e->next) {
+ // if(e->occupied) {
+ // e->terminal_vertex = v->pred_vertex;
+ // e->length = - e->length;
+ // e->work_length = 0;
+ // v->pred_vertex->del_edge(e);
+ // v->add_edge(e);
+ // }
+ // }
+ // }
+
+
+ delete[] front;
+ delete[] new_front;
}
//////////////////////////////////////////////////////////////////////
(*file) >> nb_vertices >> nb_edges;
(*file) >> source >> sink;
- cout << "INPUT nb_edges " << nb_edges << endl;
- cout << "INPUT nb_vertices " << nb_vertices << endl;
- cout << "INPUT source " << source << endl;
- cout << "INPUT sink " << sink << endl;
+ // cout << "INPUT nb_edges " << nb_edges << endl;
+ // cout << "INPUT nb_vertices " << nb_vertices << endl;
+ // cout << "INPUT source " << source << endl;
+ // cout << "INPUT sink " << sink << endl;
scalar_t *el = new scalar_t[nb_edges];
int *ea = new int[nb_edges];
for(int e = 0; e < nb_edges; e++) {
(*file) >> ea[e] >> eb[e] >> el[e];
- cout << "INPUT_EDGE " << ea[e] << " " << eb[e] << " " << el[e] << endl;
}
+ // for(int e = 0; e < nb_edges; e++) {
+ // cout << "INPUT_EDGE " << ea[e] << " " << eb[e] << " " << el[e] << endl;
+ // }
+
Graph graph(nb_vertices, nb_edges, ea, eb, el, source, sink);
graph.find_best_paths();
- graph.print_occupied_edges();
+ // graph.print_occupied_edges();
+ graph.dot_print();
delete[] el;
delete[] ea;