Breadth First Search,广度优先搜索(遍历),BFS实现一般基于队列。队列在广度优先搜索遍历中是关键点。
(1)队列Q在弹出最左边头部的节点V的同时,要把与V邻接的子节点立即加入队列Q的尾部。然后在while循环中重复处理(弹出最最左边头部的节点)。直到队列的长度为0,循环结束,也即算法完成遍历搜索。
(2)本例基于networkx实现,networkx提供了节点、图、边的现成工具,只需要按照需要记录节点的访问情况,当每一个节点作为顶点被弹出时候,标记它为已访问(visited=true),全图搜索路径由此产生。
一个例子:
import networkx as nx import matplotlib.pyplot as plt from collections import deque # 记录搜索路径 search_path = [] def my_graph(): G = nx.gnm_random_graph(n=6, m=8) # G = nx.balanced_tree(r=2, h=3) pos = nx.spring_layout(G) nx.draw_networkx(G, pos, node_color='green', node_size=300, font_size=10, font_color='white', edge_color='gray', width=1, with_labels=True) print('G.nodes(data=True)', G.nodes(data=True)) bfs(G) plt.show() # 基于队列实现广度优先遍历 def bfs(G): for n in G.nodes(): G.nodes[n]['visited'] = False print(G.nodes(data=True)) V = 0 Q = deque() Q.append(V) while True: if len(Q) == 0: break print('-----') print('Q', Q) node = Q.popleft() # 左边最头部含有上一轮父层次的节点 print('弹出', node) G.nodes[node]['visited'] = True search_path.append(node) print('search_path', search_path) for n in nx.neighbors(G, node): # 注意,如果n已经在队列里面,则不予重复添加。 if (not G.nodes[n]['visited']) and (n not in Q): Q.append(n) print('Q append', Q) # print('search_path', search_path) print('=====') print('\n标准的networkx广度优先搜索:') print(list(nx.bfs_tree(G, source=0))) if __name__ == '__main__': my_graph()
生成图:
运行日志:
G.nodes(data=True) [(0, {}), (1, {}), (2, {}), (3, {}), (4, {}), (5, {})] [(0, {'visited': False}), (1, {'visited': False}), (2, {'visited': False}), (3, {'visited': False}), (4, {'visited': False}), (5, {'visited': False})] ----- Q deque([0]) 弹出 0 search_path [0] Q append deque([1, 3, 4]) ----- Q deque([1, 3, 4]) 弹出 1 search_path [0, 1] Q append deque([3, 4, 5]) ----- Q deque([3, 4, 5]) 弹出 3 search_path [0, 1, 3] Q append deque([4, 5]) ----- Q deque([4, 5]) 弹出 4 search_path [0, 1, 3, 4] Q append deque([5, 2]) ----- Q deque([5, 2]) 弹出 5 search_path [0, 1, 3, 4, 5] Q append deque([2]) ----- Q deque([2]) 弹出 2 search_path [0, 1, 3, 4, 5, 2] Q append deque([]) ===== 标准的networkx广度优先搜索: [0, 1, 3, 4, 5, 2]