networkx图论Depth First Search深度优先搜索遍历DFS,基于递归,Python
DFS又称为深度优先遍历,在图论中用于搜索图中的点和路径。简单写一个Python实现,图的表示用networkx。networkx本身提供了节点连接的结构已经提供了对节点状态值保存的便捷手段。
在每个节点中存放一个visited值,boolean类型,如果已经访问过,记为true,不再搜索遍历。
import networkx as nx
import matplotlib.pyplot as plt
# 记录搜索路径
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))
dfs(G)
plt.show()
def dfs(G):
for n in G.nodes():
G.nodes[n]['visited'] = False
print(G.nodes(data=True))
print('-----')
V = 0
G.nodes[V]['visited'] = True
search_path.append(V)
travel(G, V)
print(search_path)
print('=====')
print('\n标准的networkx深度优先搜索:')
print(list(nx.dfs_tree(G, source=0)))
def travel(G, V):
neighbors = nx.neighbors(G, V)
for n in neighbors:
if not G.nodes[n]['visited']:
# 为已经访问过的节点打上标记
G.nodes[n]['visited'] = True
search_path.append(n)
# 针对某个节点深入遍历搜索
travel(G, n)
if __name__ == '__main__':
my_graph()
生成图:
运行日志:
G.nodes(data=True) [(0, {}), (1, {}), (2, {}), (3, {}), (4, {}), (5, {}), (6, {}), (7, {}), (8, {}), (9, {}), (10, {}), (11, {}), (12, {}), (13, {}), (14, {})]
[(0, {'visited': False}), (1, {'visited': False}), (2, {'visited': False}), (3, {'visited': False}), (4, {'visited': False}), (5, {'visited': False}), (6, {'visited': False}), (7, {'visited': False}), (8, {'visited': False}), (9, {'visited': False}), (10, {'visited': False}), (11, {'visited': False}), (12, {'visited': False}), (13, {'visited': False}), (14, {'visited': False})]
-----
[0, 1, 3, 7, 8, 4, 9, 10, 2, 5, 11, 12, 6, 13, 14]
=====
标准的networkx深度优先搜索:
[0, 1, 3, 7, 8, 4, 9, 10, 2, 5, 11, 12, 6, 13, 14]
上面是子节点为2,深度为3的平衡树结果。
如果图改成6个节点,8个边的无向图,则生成图为:
运行日志:
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})]
-----
[0, 1, 3, 2, 5, 4]
=====
标准的networkx深度优先搜索:
[0, 1, 3, 2, 5, 4]