1. 程式人生 > >Python刷題--Graph(find_paths/BFS/DFS/iterative/recursive)

Python刷題--Graph(find_paths/BFS/DFS/iterative/recursive)

# -*- 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)