Acessing edge property in dijkstra visitor

I want to compute the shortest path of a graph using graph-tool. While doing that, I want to count the number of times an edge is visited during the procedure and multiply it by a factor (similar to the edge betweenness).


#random graph with 500 vertices
g = gt.Graph(directed=True)
g.add_vertex(500)
gt.add_random_edges(g, 2*g.num_vertices())

#generate weights
weight = g.new_edge_property("double")
for e in g.edges():
    weight[e] = 1+np.random.rand()
g.ep.weight = weight


#compute load from origin to all targets
def load_target(L, dist_to_origin, target, pred):
    j = target
    while pred[j] != j:
        L[pred[j], j] += np.exp(-dist_to_origin)
        j = pred[j]
    return L

class Visitor(gt.DijkstraVisitor):
    def __init__(self, load, pred, dist):
        self.load = load
        self.pred = pred
        self.dist = dist

    def finish_vertex(self, u):
        pred = self.pred
        dist_to_origin = self.dist[u]
        self.load = load_target(self.load, dist_to_origin, u, pred)

dist = g.new_vertex_property("double")
pred = g.new_vertex_property("int64_t")
load = g.new_edge_property("int64_t")

#edge_list = [ (int(e.source()), int(e.target())) for e in g.edges() ]
#L = dict( zip(edge_list, np.zeros(len(edge_list)))  )

for o in g.vertices():
    dist, pred = gt.dijkstra_search(g,
                weight=g.ep.weight,
                source=g.vertex(o),
                dist_map=dist,
                pred_map=pred,
                visitor=Visitor(load, pred, dist)
                )

However this generates the error message:

    __getitem__(graph_tool::PythonPropertyMap>> {lvalue}, graph_tool::PythonEdge, boost::adj_list const&>, graph_tool::detail::MaskFilter>>, graph_tool::detail::MaskFilter>>>>)
    __getitem__(graph_tool::PythonPropertyMap>> {lvalue}, graph_tool::PythonEdge, graph_tool::detail::MaskFilter>>, graph_tool::detail::MaskFilter>>>>)
    __getitem__(graph_tool::PythonPropertyMap>> {lvalue}, graph_tool::PythonEdge>>)
    __getitem__(graph_tool::PythonPropertyMap>> {lvalue}, graph_tool::PythonEdge, boost::adj_list const&>>)
    __getitem__(graph_tool::PythonPropertyMap>> {lvalue}, graph_tool::PythonEdge>)

The problem is, that I can not access the edge property load with load[(i,j)]. It works when I call the edge properly with the graph load[g.edge(i,j)], however this is much slower because the graph has to be called every time. How do I access the edge property properly in the dijkstra visitor?

You’ve already answered your own question: you need to use load[g.edge(i,j)] not load[(i,j)]. The former is valid use of an edge property map, the latter is not.

If you want direct access to edges, without calling g.edge(), you need to overload edge_relaxed() in the visitor.

Update: in the newest version of graph-tool, the syntax load[(i,j)] is accepted. However, it is identical to calling load[g.edge(i,j)] in terms of performance. It’s there only for convenience.