Reputation: 51
Here http://www.python.org/doc/essays/graphs/ is DFS right ?
I try to do something with 'siblings', but it does not work. Can anyone write BFS similar to code from this site.
Upvotes: 5
Views: 19231
Reputation: 11
def recursive_dfs(graph, start, path=[]):
'''recursive depth first search from start'''
path=path+[start]
for node in graph[start]:
if not node in path:
path=recursive_dfs(graph, node, path)
return path
def iterative_dfs(graph, start, path=[]):
'''iterative depth first search from start'''
q=[start]
while q:
v=q.pop(0)
if v not in path:
path=path+[v]
q=graph[v]+q
return path
def iterative_bfs(graph, start, path=[]):
'''iterative breadth first search from start'''
q=[start]
while q:
v=q.pop(0)
if not v in path:
path=path+[v]
q=q+graph[v]
return path
'''
+---- A
| / \
| B--D--C
| \ | /
+---- E
'''
graph = {'A':['B','C'],'B':['D','E'],'C':['D','E'],'D':['E'],'E':['A']}
print 'recursive dfs ', recursive_dfs(graph, 'A')
print 'iterative dfs ', iterative_dfs(graph, 'A')
print 'iterative bfs ', iterative_bfs(graph, 'A')
Upvotes: 1
Reputation:
Here's an O(N * max(vertex degree)) breadth-first search implementation. The bfs function generates nodes in breadth-first order, and for each a generator that can be used to trace a shortest path back to the start point. The lazy nature of the paths means that you can iterate through the generated node to find points you're interested in without paying the cost of building all the intermediate paths.
import collections
GRAPH = {'A': ['B', 'C'],
'B': ['C', 'D'],
'C': ['D'],
'D': ['C'],
'E': ['F'],
'F': ['C']}
def build_path(node, previous_map):
while node:
yield node
node = previous_map.get(node)
def bfs(start, graph):
previous_map = {}
todo = collections.deque()
todo.append(start)
while todo:
node = todo.popleft()
yield node, build_path(node, previous)
for next_node in graph.get(node, []):
if next_node not in previous_map:
previous_map[next_node] = node
todo.append(next_node)
for node, path in bfs('A', GRAPH):
print node, list(path)
Upvotes: 1
Reputation: 46507
Yes, it is DFS.
To write a BFS you just need to keep a "todo" queue. You probably also want to turn the function into a generator because often a BFS is deliberately ended before it generates all possible paths. Thus this function can be used to be find_path or find_all_paths.
def paths(graph, start, end):
todo = [[start, [start]]]
while 0 < len(todo):
(node, path) = todo.pop(0)
for next_node in graph[node]:
if next_node in path:
continue
elif next_node == end:
yield path + [next_node]
else:
todo.append([next_node, path + [next_node]])
And an example of how to use it:
graph = {'A': ['B', 'C'],
'B': ['C', 'D'],
'C': ['D'],
'D': ['C'],
'E': ['F'],
'F': ['C']}
for path in paths(graph, 'A', 'D'):
print path
Upvotes: 8