diff --git a/test/python/py_dijkstra.py b/test/python/py_dijkstra.py new file mode 100644 index 00000000..16e77f64 --- /dev/null +++ b/test/python/py_dijkstra.py @@ -0,0 +1,109 @@ +# Copyright 2005 The Trustees of Indiana University. + +# Use, modification and distribution is subject to the Boost Software +# License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +# Authors: Douglas Gregor +# Andrew Lumsdaine + +# Note: this code requires the Boost Graph Library bindings for Python +# and the priodict module. The latter is part of the Python NMS +# library (http://pynms.sourceforge.net/). + +import bgl +import priodict + +class pqueue(bgl.Digraph.VertexQueue): + def __init__(self, distance): + bgl.Digraph.VertexQueue.__init__(self) + self.Q = priodict.priorityDictionary() + self.distance = distance + def empty(self): + return self.Q == {} + def top(self): + return self.Q.smallest(); + def pop(self): + del self.Q[self.Q.smallest()] + def push(self, x): + self.Q[x] = self.distance[x] + def update(self, x, v): + self.distance[x] = v + self.Q[x] = v + +class dijkstra_bfs_visitor(bgl.Digraph.BFSVisitor): + def __init__(self, Q, weight, distance, predecessor): + bgl.Digraph.BFSVisitor.__init__(self) + self.Q = Q + self.weight = weight + self.distance = distance + self.predecessor = predecessor + + def tree_edge(self, e, g): + (u, v) = (g.source(e), g.target(e)) + self.distance[v] = self.distance[u] + self.weight[e] + self.predecessor[v] = u + + def gray_target(self, e, g): + (u, v) = (g.source(e), g.target(e)) + if self.distance[u] + self.weight[e] < self.distance[v]: + self.Q.update(v, self.distance[u] + self.weight[e]) + self.predecessor[v] = u; + + +g = bgl.Digraph() + +# Create vertices in the graph +name = g.get_vertex_string_map("node_id") +A = g.add_vertex() +name[A] = "A" +B = g.add_vertex() +name[B] = "B" +C = g.add_vertex() +name[C] = "C" +D = g.add_vertex() +name[D] = "D" +E = g.add_vertex() +name[E] = "E" + +# Create (weighted) edges in the graph +weight = g.get_edge_double_map("weight") +weight[g.add_edge(A, C)] = 1 +weight[g.add_edge(B, B)] = 2 +weight[g.add_edge(B, D)] = 1 +weight[g.add_edge(B, E)] = 2.5 +weight[g.add_edge(C, B)] = 7 +weight[g.add_edge(C, D)] = 3 +weight[g.add_edge(D, E)] = 1 +weight[g.add_edge(E, A)] = 1 +weight[g.add_edge(E, B)] = 1 + +# Initialize property maps +predecessor = {} +distance = g.get_vertex_double_map("distance_from_A") +for v in g.vertices: + predecessor[v] = v + distance[v] = 1e100 + +# Run breadth-first search to compute shortest paths +distance[A] = 0 +buf = pqueue(distance) + +bgl.breadth_first_search(g, A, buf, + dijkstra_bfs_visitor(buf,weight,distance,predecessor), + color_map = g.get_vertex_color_map("color")) + +class show_relaxed_edges(bgl.Digraph.DijkstraVisitor): + def edge_relaxed(self, e, g): + text = "Relaxed edge (" + name[g.source(e)] + ", " + name[g.target(e)] + ")" + print text + +# Run Dijkstra's algorithm to compute shortest paths +distance2 = g.get_vertex_double_map("distance_from_A_also"); +bgl.dijkstra_shortest_paths(g, A, distance_map = distance2, + visitor=show_relaxed_edges()); + +# Emit graph +g.write_graphviz("dijkstra-example.dot") + +