Hi all,

First, thanks very much for creating this library. It has helped me a great deal to fiddle with graph algorithms in the comfort of my favourite language!

I'm currently having trouble performing an astar search on an explicit undirected graph. The graph I have is not crazy large (50,000 vertices with ~150,000 edges), but I need to perform a large number of astar searches (on the order of the number of vertices). As the python visitor class instance is required for the astar to terminate, it seems I'm having quite poor performance as a result of many calls back to python:

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
 88138526  116.708    0.000  153.115    0.000 __init__.py:113(wrapped_visitor_member)
     4202  110.596    0.026  302.442    0.072 __init__.py:1195(astar_search)
 88138526   34.008    0.000   38.130    0.000 __init__.py:107(__getattr__)
264384698   30.718    0.000   30.718    0.000 {method 'update' of 'dict' objects}
 88090728    5.512    0.000    5.512    0.000 __init__.py:1132(initialize_vertex)
 88138690    4.122    0.000    4.122    0.000 {built-in method callable}
    33616    0.146    0.000    0.152    0.000 __init__.py:1415(vertex)

In this case, the only function in my visitor class that is defined is:
def edge_relaxed(self, e):
        if e.target() == self.end:
            raise StopSearch()

I've also tried looking at doing the search implicitly, but I can't for the life of me get it to work. I tried to copy the original euclidean astar example from the documentation and convert it to implicit, but it doesn't seem to work. Could anyone tell me what I'm doing wrong here? I'm guessing that some of the function arguments listed as optional are not so ;)

from graph_tool.search import StopSearch, AStarVisitor, astar_search
import graph_tool.generation as gt

from numpy.random import random
from math import sqrt

class VisitorExample(AStarVisitor):

    def __init__(self, touched_v, touched_e, target):
        self.touched_v = touched_v
        self.touched_e = touched_e
        self.target = target

    def discover_vertex(self, u):
        self.touched_v[u] = True

    def examine_edge(self, e):
        self.touched_e[e] = True

    def edge_relaxed(self, e):
        if e.target() == self.target:
            raise StopSearch()
            
def h(v, target, pos):
    return sqrt(sum((pos[v].a - pos[target].a) ** 2))

points = random((500, 2)) * 4
points[0] = [-0.01, 0.01]
points[1] = [4.01, 4.01]
g, pos = gt.triangulation(points, type="delaunay")
weight = g.new_edge_property("double") # Edge weights corresponding to
                                       # Euclidean distances
for e in g.edges():
    weight[e] = sqrt(sum((pos[e.source()].a -
                         pos[e.target()].a) ** 2))
touch_v = g.new_vertex_property("bool")
touch_e = g.new_edge_property("bool")

target = g.vertex(1)
dist, pred = astar_search(g, g.vertex(0), weight,
                             VisitorExample(touch_v, touch_e, target), implicit=True,
                             heuristic=lambda v: h(v, target, pos)) 

print(pred.a)

# output is:

[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
-- 

I'd rather not implement my solution in C++, because BGL looks complex to say the least!

Thanks,
Jeremy