Python刷題--Graph(find_paths/BFS/DFS/iterative/recursive)
阿新 • • 發佈:2018-12-09
# -*- coding:UTF-8 -*-
def dfs(graph, start):
visited, stack = set(), [start]
while stack:
vertex = stack.pop()
if vertex not in visited:
visited.add(vertex)
stack.extend(graph[vertex] - visited)
return visited
# DFS
def find_path(graph, start, end, path=[]) :
path = path + [start]
if start == end:
return path
if not graph.has_key(start):
return None
for node in graph[start]:
if node not in path:
newpath = find_path(graph, node, end, path)
if newpath:
return newpath
return None
def find_all_paths(graph, start, end, path=[]):
path = path + [start]
if start == end:
return [path]
if not graph.has_key(start):
return []
paths = []
for node in graph[start]:
if node not in path:
newpaths = find_all_paths(graph, node, end, path)
for newpath in newpaths:
paths.append(newpath)
return paths
def find_shortest_path(graph, start, end, path=[]):
path = path + [start]
if start == end:
return path
if not graph.has_key(start):
return None
shortest = None
for node in graph[start]:
if node not in path:
newpath = find_shortest_path(graph, node, end, path)
if newpath:
if not shortest or len(newpath) < len(shortest):
shortest = newpath
return shortest
# BFS
def find_all_paths_bfs(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]])
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
if __name__ == '__main__':
graph = {'A': ['B', 'C'],
'B': ['C', 'D'],
'C': ['D'],
'D': ['C'],
'E': ['F'],
'F': ['C']}
print find_path(graph, 'A', 'D')
print find_all_paths(graph, 'A', 'D')
print find_shortest_path(graph, 'A', 'D')
print("##" * 20)
for path in find_all_paths_bfs(graph, 'A', 'D'):
print path
print("##" * 20)
'''
+---- 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')
print("##" * 20)