mirror of
https://github.com/boostorg/graph.git
synced 2026-01-26 18:42:12 +00:00
BSF and Dijkstra example and test
[SVN r27553]
This commit is contained in:
109
test/python/py_dijkstra.py
Normal file
109
test/python/py_dijkstra.py
Normal file
@@ -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")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user