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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.5 - (hide 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 joko 1.1 #!/usr/bin/env python
2    
3 joko 1.5 # $Id: boostgraph.py,v 1.4 2008/02/21 11:29:07 joko Exp $
4 joko 1.1
5     # (c) 2008 Andreas Motl <andreas.motl@ilo.de>
6 joko 1.3 # (c) 2008 Sebastian Utz <su@rotamente.com>
7 joko 1.1
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 joko 1.2 # 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 joko 1.1 # - 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 joko 1.3 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 joko 1.1 import sys, os
53 joko 1.3 import random
54 joko 1.1
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 joko 1.3 #class tree_edges_bfs_visitor(bgl.bfs_visitor):
65 joko 1.1
66 joko 1.4 def __init__(self, startVertex, endVertex, maxdepth, color_map):
67 joko 1.3
68 joko 1.5 print dir(self)
69 joko 1.3
70 joko 1.1 #bgl.dfs_visitor.__init__(self)
71 joko 1.4 #self.name_map = name_map
72    
73     self.startVertex = startVertex
74     self.endVertex = endVertex
75 joko 1.2
76     # for recognizing path switches
77 joko 1.1 self.state = True
78 joko 1.2
79     # for tracking paths
80     self.paths = []
81     self.current_path = []
82 joko 1.3
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 joko 1.5 def back_edge(self, e, g):
94     self._touch_edge(e, g, 'back_edge')
95 joko 1.4
96 joko 1.5 def forward_or_cross_edge(self, e, g):
97     self._touch_edge(e, g, 'forward_or_cross_edge')
98 joko 1.4
99 joko 1.5 def tree_edge(self, e, g):
100     self._touch_edge(e, g, 'tree_edge')
101 joko 1.4
102 joko 1.3 def examine_edge(self, e, g):
103 joko 1.4 self._touch_edge(e, g, 'examine_edge')
104 joko 1.1
105 joko 1.4 def _touch_edge(self, e, g, label=''):
106 joko 1.3
107 joko 1.1 (u, v) = (g.source(e), g.target(e))
108 joko 1.3
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 joko 1.4
122     name_map = g.vertex_properties['node_id']
123 joko 1.3
124     if label:
125 joko 1.5 print "%s:\t" % label,
126     #print "edge ",
127 joko 1.4 print name_map[u],
128 joko 1.1 print " -> ",
129 joko 1.4 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 joko 1.5
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 joko 1.1
170 joko 1.4 """
171 joko 1.1 def start_vertex(self, v, g):
172 joko 1.3 self._seperator('start_vertex')
173     #pass
174 joko 1.1 #print 'sssss'
175    
176 joko 1.3 def discover_vertex(self, v, g):
177     #print '>>>'
178     self._seperator('discover_vertex')
179     #pass
180    
181 joko 1.1 def initialize_vertex(self, v, g):
182     #print '>>>'
183 joko 1.2 self._seperator('initialize_vertex')
184 joko 1.1
185 joko 1.3 def examine_vertex(self, v, g):
186     self._seperator('examine_vertex')
187    
188 joko 1.1 def finish_vertex(self, v, g):
189     #print '<<<'
190 joko 1.2 if self.current_path:
191     self.paths.append(self.current_path)
192     self.current_path = []
193 joko 1.3 self.depth = 0
194 joko 1.2 self._seperator('finish_vertex')
195 joko 1.4 """
196 joko 1.1
197 joko 1.2 def _seperator(self, label = 'unknown'):
198 joko 1.3 if 1 or self.state:
199 joko 1.2 print '-' * 21, label
200 joko 1.1 self.state = False
201    
202 joko 1.2
203 joko 1.1 def build_fixed_graph():
204 joko 1.2
205 joko 1.1 graph = bgl.Graph()
206 joko 1.2 index = {}
207 joko 1.1
208 joko 1.2 # doesn't this work? see http://www.nabble.com/-Graph--Getting-PageRank-to-work-in-BGL-Python-td14207115.html
209 joko 1.1 #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 joko 1.2 index['1'] = v1
220 joko 1.1
221     v2 = graph.add_vertex()
222     vmap[v2] = '2'
223 joko 1.2 index['2'] = v2
224 joko 1.1
225     v3 = graph.add_vertex()
226     vmap[v3] = '3'
227 joko 1.2 index['3'] = v3
228 joko 1.1
229     v4 = graph.add_vertex()
230     vmap[v4] = '4'
231 joko 1.2 index['4'] = v4
232 joko 1.1
233     e1 = graph.add_edge(v1, v2)
234     e2 = graph.add_edge(v1, v3)
235     e3 = graph.add_edge(v3, v4)
236 joko 1.3
237     e4 = graph.add_edge(v1, v4)
238 joko 1.5 e5 = graph.add_edge(v2, v3)
239 joko 1.3 #e6 = graph.add_edge(v2, v4)
240 joko 1.1
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 joko 1.2 return (graph, index)
254 joko 1.1
255    
256 joko 1.3 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 joko 1.1
313 joko 1.4 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 joko 1.2 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 joko 1.3
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 joko 1.2
352 joko 1.1 def main():
353    
354     # Load a graph from the GraphViz file 'mst.dot'
355     #graph = bgl.Graph.read_graphviz('mst.dot')
356 joko 1.2 (graph, index) = build_fixed_graph()
357 joko 1.3 #(graph, index) = build_random_graph()
358    
359     #dump_graph(graph)
360 joko 1.1
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 joko 1.3
365 joko 1.4 """
366 joko 1.1 for root in graph.vertices:
367     print
368     print '=' * 42
369     print 'Paths originating from node %s' % graph.vertex_properties['node_id'][root]
370 joko 1.3 #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 joko 1.1 bgl.depth_first_search(graph, root_vertex = root, visitor = visitor, color_map = None)
375 joko 1.3 #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 joko 1.4 """
379 joko 1.3
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 joko 1.4 visitor = tree_edges_dfs_visitor(startVertex, endVertex, MAX_SEARCH_DEPTH, cmap)
393 joko 1.3 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 joko 1.4 #find_path_solutions(startVertex, endVertex, graph, visitor.paths)
396     for path in visitor.paths:
397     print '-' * 21
398     dump_edges(graph, path)
399 joko 1.3
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 joko 1.1
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