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]