图中节点的遍历和搜索是老生常谈的话题,这里借由python的networkx库,复习一下之前的BFS和DFS,并对A*做一些理解。
1.BFS 广度优先搜索
其基本思想是优先从当前节点的邻居节点开始搜索,如果搜索不到,再搜索邻居的邻居。其在算法设计的时候,主要考虑节点的标记和邻居的保存
利用全局变量time进行计时,在pre列表中保存每个节点的父节点。
整体流程如下:
(i)从G中任取一个节点i,检查是否访问过了(可以通过检查相应的pre元素是否为-1)
(ii)初始化:将节点i放入一个双端队列visit_list
(Ⅲ)检验队列是否为空,不为空,则从左边取一个节点,将其尚未访问的所有邻居放入双端队列中(从右端放入),并设置邻居节点的父节点(假设为j)即pre[j]=i;如果队列为空,则算法结束
import networkx as nx
from collections import deque
def BFS_visit(i,G=nx.Graph(),visit_time=[],pre=[]):
global time
visit_list=deque()
visit_list.append(i)
while visit_list:
visit=visit_list.popleft()
print visit
time=time+1
visit_time[visit-1]=time
for node in G:
if G.has_edge(visit,node) and visit_time[node-1]==-1 and node not in visit_list:
visit_list.append(node)
pre[node-1]=visit
def BFS(G=nx.Graph()):
pre=[]
visit_time=[]
i=1
components=0
while i<=G.number_of_nodes():
pre.append(-1)
visit_time.append(-1)
i=i+1
for node in G.nodes():
if pre[node-1]==-1:
BFS_visit(node,G,visit_time,pre)
components=components+1
print 'components',components
time=0
G=nx.Graph()
G.add_edges_from([(1,2),(1,3),(2,4),(2,5),(3,6),(4,8),(5,8),(3,7)])
BFS(G)
运行的结果是
2.DFS 宽度优先搜索
其基本思想是随机邻居节点访问,如果邻居节点都访问过了,则回溯到其父节点,直到图中所有节点都被访问过了。