For my current project I want to use the graph-tool library since they claim being the fastest: https://graph-tool.skewed.de/performance. I have some algorithms (shortest path, etc.) to run on really large networks, so the faster the better!
First question: Is this claim 'being the fastest' true? ;)
While trying to build a graph-tool graph fitting my needs, I figured out that its not possible to access vertex properties in a efficient way. Maybe I missed something?
My question is now, can the function "getVertexFromGraph(graph, position)" be written in a more efficient way? Or more in general: Can I check efficiently if a vertex (given by its position property) is already in the graph or not.
Thanks in advance!
import graph_tool as gt
#from graph_tool.all import *
edgeList = [[(0.5,1),(2.1,4.3)],[(2.1,4.3),(5.4,3.3)],[(5.4,3.3),(1.3,3.5)],[(4.4,3.3),(2.3,3.5)]] #A lot more coordinate values....
# Initialize the graph
routableNetwork = gt.Graph()
# Initialize the vertex property "position" to store the vertex coordinates
vpPosition = routableNetwork.new_vertex_property("vector<double>")
routableNetwork.vertex_properties["position"] = vpPosition
def getVertexFromGraph(graph, position):
"""
This method checks if a vertex, identified by its position, is in the given graph or not.
:param graph: The graph containing all vertices to check
:param position: The vertex/position to check
:return: The ID of the vertex if the vertex is already in the graph, 'None' otherwise
"""
for v in graph.vertices():
if graph.vp.position[v] == position:
return v
return None
def main():
"""
This method creates the graph by looping over all given edges, inserting every:
- non existent vertex in the graph with its coordinates (property 'position')
- edge with its corresponding length (property 'distance')
:return: -
"""
for e in edgeList:
vertex0 = getVertexFromGraph(routableNetwork,e[0])
vertex1 = getVertexFromGraph(routableNetwork,e[1])
if vertex0 == None:
vertex0 = routableNetwork.add_vertex()
routableNetwork.vertex_properties['position'][vertex0] = e[0]
if vertex1 == None:
vertex1 = routableNetwork.add_vertex()
routableNetwork.vertex_properties['position'][vertex1] = e[1]
edge = routableNetwork.add_edge(vertex0,vertex1)
#routableNetwork.edge_properties['distance'][edge] = calculateDistance(e[0][0],e[0][1],e[1][0],e[1][1])
#saveRoutableNetwork(routableNetwork)
#graph_draw(routableNetwork, vertex_text=routableNetwork.vertex_index, vertex_font_size=18, output_size=(200, 200), output="two-nodes.png")
if __name__ == "__main__":
main()
The function you are looking for is find_vertex()
:
https://graph-tool.skewed.de/static/doc/util.html#graph_tool.util.find_vertex
It is important to realize that graph-tool
achieves its speed by off-loading performance-sensitive loops from Python to C++. So whenever you iterate through the vertices, like you did in your code, you lose any advantage.
Note also that, although find_vertex()
is implemented in C++, and hence many times faster than the equivalent in pure Python, it is still an O(N) operation. For large graphs, you are better off creating a good old python dictionary that maps property values to vertices, which has an O(1) cost for lookup.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With