Below is an implementation of two graph traversals. Graph constructor creates a random graph with a fixed number of edges (fixed as a proportion of the maximum number of vertices, number_nodes-1
).
Any comments welcome, but especially data structure and algorithm comments. Tests are not implemented properly, but it is ok in this case.
import random
class Graph:
def __init__(self, number_nodes, max_number_edges = 0.5):
if (max_number_edges > 1) or (max_number_edges < 0):
raise ValueError("max_number_edges is out of range")
self.nodes_connections = {node_nb : range(node_nb+1, number_nodes) for node_nb in xrange(number_nodes)}
for key, value in self.nodes_connections.iteritems():
while len(value) > (max_number_edges * (number_nodes - key - 1)):
index_to_remove = random.randint(0, len(value)-1)
del value[index_to_remove]
def Print(self):
for key, value in self.nodes_connections.iteritems():
print key, value
def IterateInBreadth(self, start_node_id):
visited_nodes_ids = []
scheduled_nodes_ids = [start_node_id]
while scheduled_nodes_ids:
node_id = scheduled_nodes_ids[0]
new_scheduled_nodes_ids = [node for node in self.nodes_connections[node_id]
if not (node in visited_nodes_ids or node in scheduled_nodes_ids)]
new_scheduled_nodes_ids += [key for key, value in self.nodes_connections.iteritems()
if (node_id in value) and not (key in visited_nodes_ids or key in scheduled_nodes_ids)]
scheduled_nodes_ids += new_scheduled_nodes_ids
visited_nodes_ids.append(node_id)
del scheduled_nodes_ids[0]
return visited_nodes_ids
def __IterateInDepth(self, start_node_id, visited_nodes):
visited_nodes.append(start_node_id)
for key, value in self.nodes_connections.iteritems():
if start_node_id in value:
if key not in visited_nodes:
self.__IterateInDepth(start_node_id = key, visited_nodes = visited_nodes)
for value in self.nodes_connections[start_node_id]:
if value not in visited_nodes:
self.__IterateInDepth(start_node_id = value, visited_nodes = visited_nodes)
def IterateInDepth(self, start_node_id):
visited_nodes = []
self.__IterateInDepth(start_node_id, visited_nodes = visited_nodes)
return visited_nodes
if __name__ == '__main__':
#random.seed(1000)
g = Graph(number_nodes = 11, max_number_edges = 0.33)
g.Print()
print g.IterateInBreadth(8)
print g.IterateInBreadth(0)
print g.IterateInDepth(8)
print g.IterateInDepth(0)
networkx
here. It's a lightweight python module for graphs that is increasingly widely used. It has breadth-first and depth-first implementations already, but even if you're interested in your own versions of those, its existingGraph
classes could be useful for you and make it easier for folks to understand. \$\endgroup\$