graph/test/python/py_dijkstra.py
Douglas Gregor 2577136447 Converted to Boost Software License
[SVN r27800]
2005-03-24 14:54:12 +00:00

111 lines
3.1 KiB
Python

# 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("label")
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(),
weight_map = g.get_edge_double_map("label"));
# Emit graph
g.write_graphviz("dijkstra-example.dot")