38 |
|
|
39 |
|
|
40 |
RANDOM_MAX_NODES = 10 |
RANDOM_MAX_NODES = 10 |
41 |
RANDOM_MAX_CHILDREN_PER_NODE = 500 |
RANDOM_MAX_CHILDREN_PER_NODE = 10 |
42 |
MAX_SEARCH_DEPTH = 50 |
MAX_SEARCH_DEPTH = 50 |
43 |
|
|
44 |
|
|
45 |
|
DEBUG = True |
46 |
|
DEBUG = False |
47 |
|
|
48 |
ENABLE_PROFILING = False |
ENABLE_PROFILING = False |
49 |
|
|
50 |
if ENABLE_PROFILING: |
if ENABLE_PROFILING: |
63 |
|
|
64 |
|
|
65 |
# from http://www.boost.org/libs/graph/doc/DFSVisitor.html |
# from http://www.boost.org/libs/graph/doc/DFSVisitor.html |
66 |
class tree_edges_dfs_visitor(bgl.dfs_visitor): |
#class tree_edges_dfs_visitor(bgl.dfs_visitor): |
67 |
|
class dfs_visitor_debug(bgl.dfs_visitor): |
68 |
#class tree_edges_bfs_visitor(bgl.bfs_visitor): |
#class tree_edges_bfs_visitor(bgl.bfs_visitor): |
69 |
|
|
70 |
def __init__(self, startVertex, endVertex, maxdepth, color_map): |
def __init__(self, startVertex, endVertex, maxdepth, color_map): |
204 |
self.state = False |
self.state = False |
205 |
|
|
206 |
|
|
207 |
|
class tree_edges_dfs_visitor(bgl.dfs_visitor): |
208 |
|
|
209 |
|
def __init__(self, startVertex, endVertex, maxdepth, color_map): |
210 |
|
|
211 |
|
#print dir(self) |
212 |
|
|
213 |
|
#bgl.dfs_visitor.__init__(self) |
214 |
|
#self.name_map = name_map |
215 |
|
|
216 |
|
self.startVertex = startVertex |
217 |
|
self.endVertex = endVertex |
218 |
|
|
219 |
|
# for recognizing path switches |
220 |
|
self.state = True |
221 |
|
|
222 |
|
# for tracking paths |
223 |
|
self.paths = [] |
224 |
|
self.current_path = [] |
225 |
|
|
226 |
|
# for limiting search depth |
227 |
|
""" |
228 |
|
self.color_map = color_map |
229 |
|
self.maxdepth = maxdepth |
230 |
|
self.depth = 0 |
231 |
|
""" |
232 |
|
|
233 |
|
self.level = 0 |
234 |
|
|
235 |
|
def tree_edge(self, e, g): |
236 |
|
self._touch_edge(e, g, 'tree_edge') |
237 |
|
|
238 |
|
def forward_or_cross_edge(self, e, g): |
239 |
|
#self._touch_edge(e, g, 'forward_or_cross_edge') |
240 |
|
self.find_new_variations_from_source(e, g) |
241 |
|
self.find_new_variations_to_target(e, g) |
242 |
|
|
243 |
|
|
244 |
|
def find_new_variations_from_source(self, e, g): |
245 |
|
# find additional solutions as parts of already established ones (e.g. shortcuts) |
246 |
|
localEndVertex = g.target(e) |
247 |
|
path_additional = [] |
248 |
|
for path in self.paths: |
249 |
|
found = False |
250 |
|
for edge in path: |
251 |
|
if found: |
252 |
|
path_additional.append(edge) |
253 |
|
else: |
254 |
|
if g.source(edge) == localEndVertex: |
255 |
|
#print "found2" |
256 |
|
found = True |
257 |
|
path_additional.append(e) |
258 |
|
path_additional.append(edge) |
259 |
|
|
260 |
|
#print "find_new_variations_from_source:", path_additional |
261 |
|
if path_additional: |
262 |
|
self.paths.append(path_additional) |
263 |
|
|
264 |
|
def find_new_variations_to_target(self, e, g): |
265 |
|
# find additional solutions as parts of already established ones (e.g. shortcuts) |
266 |
|
localStartVertex = g.source(e) |
267 |
|
localEndVertex = g.target(e) |
268 |
|
|
269 |
|
#return |
270 |
|
|
271 |
|
#if not (self.endVertex == localEndVertex and self.startVertex != localStartVertex): |
272 |
|
if not (self.endVertex == localEndVertex): |
273 |
|
return |
274 |
|
|
275 |
|
# find "direct" solution (start- and end-vertices are directly connected) |
276 |
|
if self.startVertex == localStartVertex: |
277 |
|
self.paths.append([e]) |
278 |
|
return |
279 |
|
|
280 |
|
#print "check" |
281 |
|
path_additional = [] |
282 |
|
for path_iter in self.paths: |
283 |
|
found = False |
284 |
|
path = list(path_iter) |
285 |
|
path.reverse() |
286 |
|
for edge in path: |
287 |
|
if found: |
288 |
|
path_additional.insert(0, edge) |
289 |
|
else: |
290 |
|
if g.target(edge) == localStartVertex: |
291 |
|
#print "found2" |
292 |
|
found = True |
293 |
|
path_additional.append(e) |
294 |
|
path_additional.insert(0, edge) |
295 |
|
|
296 |
|
#print "find_new_variations_to_target:", path_additional |
297 |
|
if path_additional: |
298 |
|
self.paths.append(path_additional) |
299 |
|
|
300 |
|
def _touch_edge(self, e, g, label=''): |
301 |
|
|
302 |
|
(u, v) = (g.source(e), g.target(e)) |
303 |
|
|
304 |
|
# increase current search depth (level) |
305 |
|
""" |
306 |
|
self.depth += 1 |
307 |
|
|
308 |
|
# check if maximum depth reached |
309 |
|
if self.depth == self.maxdepth: |
310 |
|
# color all succeeding vertices to black (mark as "already visited") |
311 |
|
# BUG!!! marks too many nodes |
312 |
|
for child_edge in g.out_edges(v): |
313 |
|
end_vertex = g.target(child_edge) |
314 |
|
#self.color_map[end_vertex] = bgl.Color(bgl.Color.gray) |
315 |
|
""" |
316 |
|
|
317 |
|
name_map = g.vertex_properties['node_id'] |
318 |
|
|
319 |
|
if DEBUG: |
320 |
|
if label: |
321 |
|
print "%s:\t" % label, |
322 |
|
#print "edge ", |
323 |
|
print name_map[u], |
324 |
|
print " -> ", |
325 |
|
print name_map[v] |
326 |
|
|
327 |
|
#self.state = True |
328 |
|
|
329 |
|
if u == self.startVertex: |
330 |
|
#print "starting" |
331 |
|
self.current_path = [] |
332 |
|
|
333 |
|
# skip circular references |
334 |
|
if v != self.startVertex: |
335 |
|
self.current_path.append(e) |
336 |
|
|
337 |
|
# finish current path if target found |
338 |
|
if v == self.endVertex and self.current_path: |
339 |
|
#print "found:" |
340 |
|
#print self.current_path |
341 |
|
self.paths.append(self.current_path) |
342 |
|
self.current_path = [] |
343 |
|
|
344 |
|
|
345 |
def build_fixed_graph(): |
def build_fixed_graph(): |
346 |
|
|
347 |
graph = bgl.Graph() |
graph = bgl.Graph() |
378 |
|
|
379 |
e4 = graph.add_edge(v1, v4) |
e4 = graph.add_edge(v1, v4) |
380 |
e5 = graph.add_edge(v2, v3) |
e5 = graph.add_edge(v2, v3) |
381 |
#e6 = graph.add_edge(v2, v4) |
e6 = graph.add_edge(v2, v4) |
382 |
|
|
383 |
""" |
""" |
384 |
for vertex in graph.vertices: |
for vertex in graph.vertices: |
489 |
startIndex = graph.vertex_properties['node_id'][u] |
startIndex = graph.vertex_properties['node_id'][u] |
490 |
endIndex = graph.vertex_properties['node_id'][v] |
endIndex = graph.vertex_properties['node_id'][v] |
491 |
print "%s -> %s" % (startIndex, endIndex) |
print "%s -> %s" % (startIndex, endIndex) |
492 |
|
|
493 |
|
def dump_edges_vertices(graph, edge_list): |
494 |
|
startVertex = graph.source(edge_list[0]) |
495 |
|
|
496 |
|
track = [] |
497 |
|
track.append(startVertex) |
498 |
|
|
499 |
|
for edge in edge_list: |
500 |
|
endVertex = graph.target(edge) |
501 |
|
track.append(endVertex) |
502 |
|
dump_track(graph, track) |
503 |
|
|
504 |
|
def print_path_solutions(graph, paths): |
505 |
|
for path in paths: |
506 |
|
if DEBUG: |
507 |
|
print '-' * 21 |
508 |
|
dump_edges(graph, path) |
509 |
|
dump_edges_vertices(graph, path) |
510 |
|
|
511 |
|
|
512 |
|
|
513 |
def main(): |
def main(): |
514 |
|
|
515 |
# Load a graph from the GraphViz file 'mst.dot' |
# Load a graph from the GraphViz file 'mst.dot' |
516 |
#graph = bgl.Graph.read_graphviz('mst.dot') |
#graph = bgl.Graph.read_graphviz('mst.dot') |
517 |
|
|
518 |
|
# 1. fixed graph with fixed required solution |
519 |
(graph, index) = build_fixed_graph() |
(graph, index) = build_fixed_graph() |
520 |
|
startIndex = '1' |
521 |
|
endIndex = '4' |
522 |
|
|
523 |
|
# 2. random graph with according solution |
524 |
#(graph, index) = build_random_graph() |
#(graph, index) = build_random_graph() |
525 |
|
#startIndex = random.choice(index.keys()) |
526 |
|
#endIndex = random.choice(index.keys()) |
527 |
|
|
528 |
#dump_graph(graph) |
print '-' * 42 |
529 |
|
print "complete graph:" |
530 |
|
dump_graph(graph) |
531 |
|
print '-' * 42 |
532 |
|
|
533 |
# Compute all paths rooted from each vertex |
# Compute all paths rooted from each vertex |
534 |
#mst_edges = bgl.kruskal_minimum_spanning_tree(graph, weight) |
#mst_edges = bgl.kruskal_minimum_spanning_tree(graph, weight) |
549 |
#sys.exit(0) |
#sys.exit(0) |
550 |
""" |
""" |
551 |
|
|
|
startIndex = random.choice(index.keys()) |
|
|
endIndex = random.choice(index.keys()) |
|
|
startIndex = '1' |
|
|
endIndex = '4' |
|
|
|
|
552 |
print "Trying to find solution for: %s -> %s" % (startIndex, endIndex) |
print "Trying to find solution for: %s -> %s" % (startIndex, endIndex) |
553 |
|
|
554 |
startVertex = index[startIndex] |
startVertex = index[startIndex] |
560 |
bgl.depth_first_search(graph, root_vertex = startVertex, visitor = visitor, color_map = None) |
bgl.depth_first_search(graph, root_vertex = startVertex, visitor = visitor, color_map = None) |
561 |
#bgl.depth_first_visit(graph, root_vertex = startVertex, visitor = visitor, color_map = cmap) |
#bgl.depth_first_visit(graph, root_vertex = startVertex, visitor = visitor, color_map = cmap) |
562 |
#find_path_solutions(startVertex, endVertex, graph, visitor.paths) |
#find_path_solutions(startVertex, endVertex, graph, visitor.paths) |
563 |
for path in visitor.paths: |
print '-' * 42 |
564 |
print '-' * 21 |
print "solution(s):" |
565 |
dump_edges(graph, path) |
print_path_solutions(graph, visitor.paths) |
566 |
|
|
567 |
if ENABLE_PROFILING: |
if ENABLE_PROFILING: |
568 |
global paths |
global paths |