假设你居住在旧金山,要从双子峰前往金门大桥。你想乘公交车前往,并希望换乘最少。可乘坐的公交车如下
要确定如何从双子峰前往金门大桥,需要两个步骤。
❑ 使用图来建立问题模型
❑ 使用广度优先搜索解决问题
图
图由节点和边组成。一个节点可能与众多节点直接相连,这些节点被称为邻居。
广度优先搜索
广度优先搜索(BFS)由 Edward F. Moore 在 1950 年发表,起初被用于在迷宫中寻找最短路径。在 Prim 最小生成树算法和 Dijkstra 单源最短路径算法中,都采用了与广度优先搜索类似的思想。
广度优先搜索(BFS:Breadth-First Search)是一种图搜索策略,是一种用于图的查找算法,可帮助回答两类问题。
❑ 第一类问题:从节点A出发,有前往节点B的路径吗?
❑ 第二类问题:从节点A出发,前往节点B的哪条路径最短?
一度关系胜过二度关系,二度关系胜过三度关系,以此类推。因此,你应先在一度关系中搜索
实现图
散列表可以将键映射到值。在这里,要将节点映射到其所有邻居。
有向图(directed graph)
无向图(undirected graph)没有箭头
graph = {}
graph['you'] = ['alice', 'bob', 'claire']
graph['bob'] = ['anuj', 'peggy']
graph['alice'] = ['peggy']
graph['claire'] = ['thom', 'jonny']
graph['anuj'] = []
graph['peggy'] = []
graph['thom'] = []
graph['jonny'] = []
实现算法
#!/usr/bin/env python
#coding: utf8
from collections import deque
# graph implementation
# ![13-06-54-qZxggN](http://images-9f2tzek0uc.qiniu.echosoul.cn/uPic/2020/05/22/13-06-54-qZxggN.png)
graph = {}
graph['you'] = ['alice', 'bob', 'claire']
graph['bob'] = ['anuj', 'peggy']
graph['alice'] = ['peggy']
graph['claire'] = ['thom', 'jonny']
graph['anuj'] = []
graph['peggy'] = []
graph['thom'] = []
graph['jonny'] = []
# search implementation
def search(name):
# maintain a queue of paths
search_queue = deque()
# push the first path into the queue
search_queue.append([name])
searched = []
while search_queue:
# get the path from the queue
path = search_queue.popleft()
# get the last person from the path
person = path[-1]
# if person have been checked
if person in searched:
continue
# person found
if person_is_seller(person):
print('path is: {}'.format(path))
print(person + ' is s mongo seller.')
return True
# add adjacent to increase the length of each path
for adjacent in graph.get(person, []):
new_path = path + [adjacent]
search_queue.append(new_path)
searched.append(person)
return False
def person_is_seller(name):
if name.endswith('m'):
return True
else:
return False
search('you')
时间复杂度
广度优先搜索的运行时间为O(节点+边数),这通常写作O(V+E),其中V为节点(vertice)数,E为边数。
这里的复杂度还没搞清楚。