networkx图论Breadth First Search广度优先搜索遍历BFS,基于队列,Python

x33g5p2x  于2021-11-11 转载在 Python  
字(1.8k)|赞(0)|评价(0)|浏览(730)

Breadth First Search,广度优先搜索(遍历),BFS实现一般基于队列。队列在广度优先搜索遍历中是关键点。

(1)队列Q在弹出最左边头部的节点V的同时,要把与V邻接的子节点立即加入队列Q的尾部。然后在while循环中重复处理(弹出最最左边头部的节点)。直到队列的长度为0,循环结束,也即算法完成遍历搜索。

(2)本例基于networkx实现,networkx提供了节点、图、边的现成工具,只需要按照需要记录节点的访问情况,当每一个节点作为顶点被弹出时候,标记它为已访问(visited=true),全图搜索路径由此产生。

一个例子:

  1. import networkx as nx
  2. import matplotlib.pyplot as plt
  3. from collections import deque
  4. # 记录搜索路径
  5. search_path = []
  6. def my_graph():
  7. G = nx.gnm_random_graph(n=6, m=8)
  8. # G = nx.balanced_tree(r=2, h=3)
  9. pos = nx.spring_layout(G)
  10. nx.draw_networkx(G, pos,
  11. node_color='green',
  12. node_size=300,
  13. font_size=10,
  14. font_color='white',
  15. edge_color='gray',
  16. width=1,
  17. with_labels=True)
  18. print('G.nodes(data=True)', G.nodes(data=True))
  19. bfs(G)
  20. plt.show()
  21. # 基于队列实现广度优先遍历
  22. def bfs(G):
  23. for n in G.nodes():
  24. G.nodes[n]['visited'] = False
  25. print(G.nodes(data=True))
  26. V = 0
  27. Q = deque()
  28. Q.append(V)
  29. while True:
  30. if len(Q) == 0:
  31. break
  32. print('-----')
  33. print('Q', Q)
  34. node = Q.popleft() # 左边最头部含有上一轮父层次的节点
  35. print('弹出', node)
  36. G.nodes[node]['visited'] = True
  37. search_path.append(node)
  38. print('search_path', search_path)
  39. for n in nx.neighbors(G, node):
  40. # 注意,如果n已经在队列里面,则不予重复添加。
  41. if (not G.nodes[n]['visited']) and (n not in Q):
  42. Q.append(n)
  43. print('Q append', Q)
  44. # print('search_path', search_path)
  45. print('=====')
  46. print('\n标准的networkx广度优先搜索:')
  47. print(list(nx.bfs_tree(G, source=0)))
  48. if __name__ == '__main__':
  49. my_graph()

生成图:

运行日志:

  1. G.nodes(data=True) [(0, {}), (1, {}), (2, {}), (3, {}), (4, {}), (5, {})]
  2. [(0, {'visited': False}), (1, {'visited': False}), (2, {'visited': False}), (3, {'visited': False}), (4, {'visited': False}), (5, {'visited': False})]
  3. -----
  4. Q deque([0])
  5. 弹出 0
  6. search_path [0]
  7. Q append deque([1, 3, 4])
  8. -----
  9. Q deque([1, 3, 4])
  10. 弹出 1
  11. search_path [0, 1]
  12. Q append deque([3, 4, 5])
  13. -----
  14. Q deque([3, 4, 5])
  15. 弹出 3
  16. search_path [0, 1, 3]
  17. Q append deque([4, 5])
  18. -----
  19. Q deque([4, 5])
  20. 弹出 4
  21. search_path [0, 1, 3, 4]
  22. Q append deque([5, 2])
  23. -----
  24. Q deque([5, 2])
  25. 弹出 5
  26. search_path [0, 1, 3, 4, 5]
  27. Q append deque([2])
  28. -----
  29. Q deque([2])
  30. 弹出 2
  31. search_path [0, 1, 3, 4, 5, 2]
  32. Q append deque([])
  33. =====
  34. 标准的networkx广度优先搜索:
  35. [0, 1, 3, 4, 5, 2]

相关文章