Python实现广度优先搜索的过程,需要经过以下几个步骤:
步骤一:初始化
广度优先搜索需要一个FIFO (先进先出) 的队列来存储待搜索的节点,需要将起始节点放入队列中,并标记该节点已被访问,同时初始化访问过的节点集合。
start = 'A'
visited = {start}
queue = [start]
步骤二:循环遍历队列
从队列的头部取出一个节点,检查该节点是否为目标节点,如果是,则搜索结束;否则遍历该节点的所有相邻节点,将未被访问过的相邻节点加入队列中,并将其标记为已访问的节点。
while queue:
node = queue.pop(0)
if node == goal:
print("Search success")
break
for neighbor in graph[node]:
if neighbor not in visited:
visited.add(neighbor)
queue.append(neighbor)
步骤三:构建图谱
广度优先搜索需要一个图谱表示节点之间的关系,可以用字典结构实现,其中节点是键,值是该节点的所有邻居。
graph = {'A': ['B', 'C'],
'B': ['D', 'E'],
'C': ['F', 'G'],
'D': [],
'E': ['F'],
'F': [],
'G': []}
下面通过两个示例来说明:
示例一
假设有如下无向图:
A -- B -- D
| | |
C E -- F
| |
G H
如果我们要从节点A开始搜索到节点F,那么搜索过程如下:
- 初始化:将A节点放入队列queue中,并标记为已访问visited
visited = {'A'}
queue = ['A']
- 从队列头部取出A;
- 查看其所有相邻节点,B和C,将B加入队列queue中,同时将B标记为已访问visited
queue = ['B']
visited = {'A', 'B'}
- 从队列头部取出B;
- 查看其所有相邻节点,D和E,将D加入队列queue中,同时将D标记为已访问visited
queue = ['C', 'D']
visited = {'A', 'B', 'D'}
- 从队列头部取出C;
- 查看其所有相邻节点,F和G,将F加入队列queue中,同时将F标记为已访问visited
queue = ['D', 'F']
visited = {'A', 'B', 'D', 'C', 'F'}
- 从队列头部取出D;
- 查看其所有相邻节点,无,queue不变
queue = ['F']
visited = {'A', 'B', 'D', 'C', 'F'}
- 从队列头部取出F;
- 查看其所有相邻节点,无,queue不变
queue = []
visited = {'A', 'B', 'D', 'C', 'F'}
- 搜索结束,目标节点F已找到
示例二
假设有如下有向图:
start -> A -> B -> D
| ^
v |
C -----> E ----/
|
v
goal
如果我们要从节点start开始搜索到节点goal,那么搜索过程如下:
- 初始化:将start节点放入队列queue中,并标记为已访问visited
visited = {'start'}
queue = ['start']
- 从队列头部取出start;
- 查看其所有相邻节点,A和C,将A和C加入队列queue中,同时将A和C标记为已访问visited
queue = ['A', 'C']
visited = {'start', 'A', 'C'}
- 从队列头部取出A;
- 查看其所有相邻节点,B,将B加入队列queue中,同时将B标记为已访问visited
queue = ['C', 'B']
visited = {'start', 'A', 'C', 'B'}
- 从队列头部取出C;
- 查看其所有相邻节点,E,将E加入队列queue中,同时将E标记为已访问visited
queue = ['B', 'E']
visited = {'start', 'A', 'C', 'B', 'E'}
- 从队列头部取出B;
- 查看其所有相邻节点,D,将D加入队列queue中,同时将D标记为已访问visited
queue = ['E', 'D']
visited = {'start', 'A', 'C', 'B', 'E', 'D'}
- 从队列头部取出E;
- 查看其所有相邻节点,无,queue不变
queue = ['D']
visited = {'start', 'A', 'C', 'B', 'E', 'D'}
- 从队列头部取出D;
- 查看其所有相邻节点,无,queue不变
queue = []
visited = {'start', 'A', 'C', 'B', 'E', 'D'}
- 搜索结束,目标节点goal未被访问到