/[cvs]/nfo/python/scripts/sixdegrees/boostgraph.py
ViewVC logotype

Contents of /nfo/python/scripts/sixdegrees/boostgraph.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.5 - (show annotations)
Fri Feb 22 13:34:26 2008 UTC (16 years, 5 months ago) by joko
Branch: MAIN
Changes since 1.4: +34 -12 lines
File MIME type: text/x-python
debugging related to path recording

1 #!/usr/bin/env python
2
3 # $Id: boostgraph.py,v 1.4 2008/02/21 11:29:07 joko Exp $
4
5 # (c) 2008 Andreas Motl <andreas.motl@ilo.de>
6 # (c) 2008 Sebastian Utz <su@rotamente.com>
7
8 # This program is free software: you can redistribute it and/or modify
9 # it under the terms of the GNU Affero General Public License as published by
10 # the Free Software Foundation, either version 3 of the License, or
11 # (at your option) any later version.
12 #
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU Affero General Public License for more details.
17 #
18 # You should have received a copy of the GNU Affero General Public License
19 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20
21
22
23 # Uses BGL-Python (depth_first_search)
24 #
25 # BGL-Python Homepage: http://osl.iu.edu/~dgregor/bgl-python/
26 #
27 # Documentation (Boost):
28 # - http://www.boost.org/libs/graph/doc/graph_theory_review.html
29 # - http://www.boost.org/libs/graph/doc/depth_first_search.html
30 # - http://www.boost.org/boost/graph/depth_first_search.hpp
31 # - http://www.boost.org/libs/graph/doc/DFSVisitor.html
32 # - http://www.boost.org/libs/graph/example/dfs-example.cpp
33 #
34 # Documentation (BGL-Python):
35 # - http://osl.iu.edu/~dgregor/bgl-python/reference/boost.graph.html
36 #
37 # Subversion-Repository: https://svn.osl.iu.edu/svn/projects_viz/bgl-python/
38
39
40 RANDOM_MAX_NODES = 10
41 RANDOM_MAX_CHILDREN_PER_NODE = 500
42 MAX_SEARCH_DEPTH = 50
43
44
45 ENABLE_PROFILING = False
46
47 if ENABLE_PROFILING:
48 import profile
49 from profile import Profile
50
51
52 import sys, os
53 import random
54
55 sys.path.append('bgl_python')
56 os.environ['PATH'] += ';' + './bgl_python'
57
58 import boost.graph as bgl
59
60
61
62 # from http://www.boost.org/libs/graph/doc/DFSVisitor.html
63 class tree_edges_dfs_visitor(bgl.dfs_visitor):
64 #class tree_edges_bfs_visitor(bgl.bfs_visitor):
65
66 def __init__(self, startVertex, endVertex, maxdepth, color_map):
67
68 print dir(self)
69
70 #bgl.dfs_visitor.__init__(self)
71 #self.name_map = name_map
72
73 self.startVertex = startVertex
74 self.endVertex = endVertex
75
76 # for recognizing path switches
77 self.state = True
78
79 # for tracking paths
80 self.paths = []
81 self.current_path = []
82
83 # for limiting search depth
84 """
85 self.color_map = color_map
86 self.maxdepth = maxdepth
87 self.depth = 0
88 """
89
90 self.level = 0
91
92
93 def back_edge(self, e, g):
94 self._touch_edge(e, g, 'back_edge')
95
96 def forward_or_cross_edge(self, e, g):
97 self._touch_edge(e, g, 'forward_or_cross_edge')
98
99 def tree_edge(self, e, g):
100 self._touch_edge(e, g, 'tree_edge')
101
102 def examine_edge(self, e, g):
103 self._touch_edge(e, g, 'examine_edge')
104
105 def _touch_edge(self, e, g, label=''):
106
107 (u, v) = (g.source(e), g.target(e))
108
109 # increase current search depth (level)
110 """
111 self.depth += 1
112
113 # check if maximum depth reached
114 if self.depth == self.maxdepth:
115 # color all succeeding vertices to black (mark as "already visited")
116 # BUG!!! marks too many nodes
117 for child_edge in g.out_edges(v):
118 end_vertex = g.target(child_edge)
119 #self.color_map[end_vertex] = bgl.Color(bgl.Color.gray)
120 """
121
122 name_map = g.vertex_properties['node_id']
123
124 if label:
125 print "%s:\t" % label,
126 #print "edge ",
127 print name_map[u],
128 print " -> ",
129 print name_map[v]
130
131 #self.state = True
132
133 if u == self.startVertex:
134 print "starting"
135 self.current_path = []
136
137 # skip circular references
138 if v != self.startVertex:
139 self.current_path.append(e)
140
141 if v == self.endVertex and self.current_path:
142 print "found:"
143 print self.current_path
144 self.paths.append(self.current_path)
145 self.current_path = []
146
147
148 def _touch_vertex(self, v, g, label=''):
149 name_map = g.vertex_properties['node_id']
150 id = name_map[v]
151 print '%s:\t%s' % (label, id)
152
153
154 def start_vertex(self, v, g):
155 self._touch_vertex(v, g, 'start_vertex')
156
157 def discover_vertex(self, v, g):
158 self._touch_vertex(v, g, 'discover_vertex')
159
160 def initialize_vertex(self, v, g):
161 self._touch_vertex(v, g, 'initialize_vertex')
162
163 def examine_vertex(self, v, g):
164 self._touch_vertex(v, g, 'examine_vertex')
165
166 def finish_vertex(self, v, g):
167 self._touch_vertex(v, g, 'finish_vertex')
168
169
170 """
171 def start_vertex(self, v, g):
172 self._seperator('start_vertex')
173 #pass
174 #print 'sssss'
175
176 def discover_vertex(self, v, g):
177 #print '>>>'
178 self._seperator('discover_vertex')
179 #pass
180
181 def initialize_vertex(self, v, g):
182 #print '>>>'
183 self._seperator('initialize_vertex')
184
185 def examine_vertex(self, v, g):
186 self._seperator('examine_vertex')
187
188 def finish_vertex(self, v, g):
189 #print '<<<'
190 if self.current_path:
191 self.paths.append(self.current_path)
192 self.current_path = []
193 self.depth = 0
194 self._seperator('finish_vertex')
195 """
196
197 def _seperator(self, label = 'unknown'):
198 if 1 or self.state:
199 print '-' * 21, label
200 self.state = False
201
202
203 def build_fixed_graph():
204
205 graph = bgl.Graph()
206 index = {}
207
208 # doesn't this work? see http://www.nabble.com/-Graph--Getting-PageRank-to-work-in-BGL-Python-td14207115.html
209 #graph.add_vertex_property_map(name='my_name', type='float')
210
211 # 'write_graphviz' requires property 'node_id' on vertices
212 # see http://lists.boost.org/boost-users/2006/06/19877.php
213 vmap = graph.vertex_property_map('string')
214 graph.vertex_properties['node_id'] = vmap
215
216
217 v1 = graph.add_vertex()
218 vmap[v1] = '1'
219 index['1'] = v1
220
221 v2 = graph.add_vertex()
222 vmap[v2] = '2'
223 index['2'] = v2
224
225 v3 = graph.add_vertex()
226 vmap[v3] = '3'
227 index['3'] = v3
228
229 v4 = graph.add_vertex()
230 vmap[v4] = '4'
231 index['4'] = v4
232
233 e1 = graph.add_edge(v1, v2)
234 e2 = graph.add_edge(v1, v3)
235 e3 = graph.add_edge(v3, v4)
236
237 e4 = graph.add_edge(v1, v4)
238 e5 = graph.add_edge(v2, v3)
239 #e6 = graph.add_edge(v2, v4)
240
241 """
242 for vertex in graph.vertices:
243 #print vertex.id, vertex
244 print vmap[vertex], vertex
245 #print vertex.__getattribute__('id')
246 #print vertex['id']
247 #print vertex.get('id')
248 #print
249 """
250
251 graph.write_graphviz('friends.dot')
252
253 return (graph, index)
254
255
256 def build_random_graph():
257
258 graph = bgl.Graph()
259 index = {}
260
261 vmap = graph.vertex_property_map('string')
262 graph.vertex_properties['node_id'] = vmap
263
264 count = 0
265 for parent_id in range(1, RANDOM_MAX_NODES + 1):
266 count += 1
267 if count % 100 == 0:
268 sys.stderr.write('.')
269
270 parent_id_str = str(parent_id)
271 v1New = False
272 if not index.has_key(parent_id_str):
273 #print "adding v1:", parent_id_str
274 myVertex1 = graph.add_vertex()
275 vmap[myVertex1] = parent_id_str
276 index[parent_id_str] = myVertex1
277 v1New = True
278
279
280 count = 0
281 #for j in range(1, random.randint(1, RANDOM_MAX_CHILDREN_PER_NODE)):
282 for j in range(1, RANDOM_MAX_CHILDREN_PER_NODE):
283
284 count += 1
285 if count % 100 == 0:
286 sys.stderr.write('.')
287
288 parent_id_str = random.choice(index.keys())
289
290 child_id_str = parent_id_str
291 while child_id_str == parent_id_str:
292 child_id_str = random.choice(index.keys())
293 #print child_id_str
294
295 myVertex1 = index[parent_id_str]
296 myVertex2 = index[child_id_str]
297
298 graph.add_edge(myVertex1, myVertex2)
299
300 sys.stderr.write("\n")
301
302 return (graph, index)
303
304
305 def dump_track(graph, track):
306 track_ids = []
307 for node in track:
308 node_id = graph.vertex_properties['node_id'][node]
309 track_ids.append(node_id)
310
311 print ' -> '.join(track_ids)
312
313 def dump_edges(g, edges):
314 name_map = g.vertex_properties['node_id']
315 for e in edges:
316 (u, v) = (g.source(e), g.target(e))
317 print "edge ",
318 print name_map[u],
319 print " -> ",
320 print name_map[v]
321
322 def find_path_solutions(source, target, graph, paths):
323
324 print
325 print "=" * 42
326 print "find_path_solutions"
327 print "=" * 42
328
329 #print visitor.paths
330 #(u, v) = (g.source(e), g.target(e))
331 for path in paths:
332 startVertex = graph.source(path[0])
333
334 track = []
335 track.append(startVertex)
336
337 for edge in path:
338 endVertex = graph.target(edge)
339 track.append(endVertex)
340 if source == startVertex and target == endVertex:
341 #print "found:", track
342 dump_track(graph, track)
343
344 def dump_graph(graph):
345 for edge in graph.edges:
346 (u, v) = (graph.source(edge), graph.target(edge))
347 startIndex = graph.vertex_properties['node_id'][u]
348 endIndex = graph.vertex_properties['node_id'][v]
349 print "%s -> %s" % (startIndex, endIndex)
350
351
352 def main():
353
354 # Load a graph from the GraphViz file 'mst.dot'
355 #graph = bgl.Graph.read_graphviz('mst.dot')
356 (graph, index) = build_fixed_graph()
357 #(graph, index) = build_random_graph()
358
359 #dump_graph(graph)
360
361 # Compute all paths rooted from each vertex
362 #mst_edges = bgl.kruskal_minimum_spanning_tree(graph, weight)
363 #bgl.depth_first_search(graph, root_vertex = None, visitor = None, color_map = None)
364
365 """
366 for root in graph.vertices:
367 print
368 print '=' * 42
369 print 'Paths originating from node %s' % graph.vertex_properties['node_id'][root]
370 #cmap = graph.vertex_property_map('color')
371 cmap = None
372 visitor = tree_edges_dfs_visitor(3, graph.vertex_properties['node_id'], cmap)
373 #visitor = tree_edges_bfs_visitor(3, graph.vertex_properties['node_id'], cmap)
374 bgl.depth_first_search(graph, root_vertex = root, visitor = visitor, color_map = None)
375 #bgl.breadth_first_search(graph, root_vertex = root, visitor = visitor, color_map = None)
376 #find_path_solutions(index['1'], index['4'], graph, visitor.paths)
377 #sys.exit(0)
378 """
379
380 startIndex = random.choice(index.keys())
381 endIndex = random.choice(index.keys())
382 startIndex = '1'
383 endIndex = '4'
384
385 print "Trying to find solution for: %s -> %s" % (startIndex, endIndex)
386
387 startVertex = index[startIndex]
388 endVertex = index[endIndex]
389
390 def doCompute():
391 cmap = graph.vertex_property_map('color')
392 visitor = tree_edges_dfs_visitor(startVertex, endVertex, MAX_SEARCH_DEPTH, cmap)
393 bgl.depth_first_search(graph, root_vertex = startVertex, visitor = visitor, color_map = None)
394 #bgl.depth_first_visit(graph, root_vertex = startVertex, visitor = visitor, color_map = cmap)
395 #find_path_solutions(startVertex, endVertex, graph, visitor.paths)
396 for path in visitor.paths:
397 print '-' * 21
398 dump_edges(graph, path)
399
400 if ENABLE_PROFILING:
401 global paths
402 paths = []
403 p = Profile()
404 p.runcall(doCompute)
405 p.print_stats()
406 else:
407 paths = doCompute()
408
409
410 # STOP HERE
411 sys.exit(0)
412
413
414
415
416
417 # Compute the weight of the minimum spanning tree
418 #print 'MST weight =',sum([weight[e] for e in mst_edges])
419
420 # Put the weights into the label. Make MST edges solid while all other
421 # edges remain dashed.
422 label = graph.edge_property_map('string')
423 style = graph.edge_property_map('string')
424 for e in graph.edges:
425 label[e] = str(weight[e])
426 if e in mst_edges:
427 style[e] = 'solid'
428 else:
429 style[e] = 'dashed'
430
431 # Associate the label and style property maps with the graph for output
432 graph.edge_properties['label'] = label
433 graph.edge_properties['style'] = style
434
435 # Write out the graph in GraphViz DOT format
436 graph.write_graphviz('friends_path_2to3.dot')
437
438
439 if __name__ == '__main__':
440 main()

MailToCvsAdmin">MailToCvsAdmin
ViewVC Help
Powered by ViewVC 1.1.26 RSS 2.0 feed