广度优先搜索
是一种用于图的查找算法,可帮助 回答两类问题。
- 从节点A出发,有前往节点B的路径吗?
- 从节点A出发,前往节点B的哪条路径最短?
例如,你想从你的朋友中找出谁是关系最近的芒果销售商。关系如下图。
朋友是一度关系,朋友的朋友是二度关系。
广度优先的思想是先在一 度关系中搜索,确定其中没有芒果销售商后,才在二度关系中搜索。
算法思路:
- 创建一个队列,用于存储需要检查的人。
- 从队列弹出一个人。
- 检查这个人是否是芒果供应商。
- if True:return 得到答案;else:把她的所有邻居加入队列。
- 继续回到第二步。
- 如果到列表为空都没输出结果,说明关系网中没有芒果供应商;return None。
# 数据准备
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"] = []
# 导入双端队列
from collections import deque
# 判断是否是芒果供应商(名字最后一个字符是否是 m)
def person_is_seller(name):
return name[-1] == 'm'
def breadth_first_search(data_dict):
# 避免重复检查和死循环
chacked_list = []
search_queue = deque()
search_queue.extend(data_dict['you'])
while search_queue:
person = search_queue.popleft()
if person in chacked_list:
continue
if person_is_seller(person):
print(person + " is a mango seller")
return True
else:
search_queue.extend(data_dict[person])
chacked_list.append(person)
print("no mango seler in yor frends net.")
return False
总结:
-
广度优先搜索指出是否有从A到B的路径。如果有,广度优先搜索将找出最短路径。
-
你需要按加入顺序检查搜索列表中的人,否则找到的就不是最短路径,因此搜索列表必须是队列。
-
对于检查过的人,务必不要再去检查,否则可能导致无限循环
参考