一、什么是广度优先搜索
解决最短路径问题的算法被称为广度优先搜索,广度优先搜索是一种用于图的查找算法,其可以帮助回答两类问题:
- 第一类问题:从节点A出发,有前往节点B的路径吗?
- 第二类问题:从节点A出发,前往节点B的哪条路径最短?
二、一个在人际关系中寻找芒果销售商的算法实现
图:
具体的算法过程:需要用到图的实现、散列表、队列的知识
(1)、创建一个队列,用于存储要检查的人。
(2)、从队列中弹出一个人。
(3)、检查这个人是否是芒果销售商
(4a)、如果是芒果销售商,则找到需要的人
(4b)、如果不是,则将这个人的图中所有邻居都加入队列
(5)、回到第(2)步
(6)、如果队列为空,就说明你的人际关系网络中没有芒果销售商
python语言实现
1、图的实现
因为散列表是无序的,因此添加键—值对的顺序无关紧要。Python语言的散列表是字典
#定义人之间的关系图谱,也就是图的定义
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"] = []
2、队列的创建
在python中,可以使用函数deque来创建一个双端队列。
#引入collections模块,collections是Python内建的一个集合模块,提供了许多有用的集合类。
from collections import deque
search_queue = deque() #创建一个队列
search_queue += graph[name] #将name的邻居都加入到这个搜索队列中
3、整个执行过程
4、存在的问题:
Peggy即是Alice的朋友又是Bob的朋友,因此她将被加入队列两次,这样搜索队列就将包含两个Peggy
但是你只需要检查Peggy一次,看她是不是芒果销售商,如果你检查两次,就做了无用功。因此,检查完一个人后应该将其标记为已检查,且不再检查他。如果不这样,将导致无限循环。因此可以使用一个列表来记录检查过的人。
searched = [] #定义一个数组,这个数组用于记录检查过的人
searched.append(person) #将检查过的人加入已检查的数组中
5、最终完整代码
#引入collections模块,collections是Python内建的一个集合模块,提供了许多有用的集合类。
from collections import deque
#定义一个判断人是否是芒果销售商的函数
def person_is_seller(name):
return name[-1] == 'm' #如果名字末尾是字母m,则是芒果销售商(此处只是举例演示)
#定义人之间的关系图谱,也就是图的定义
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"] = []
#定义芒果销售商的查找函数
def search(name):
search_queue = deque() #创建一个队列
search_queue += graph[name] #将name的邻居都加入到这个搜索队列中
searched = [] #定义一个数组,这个数组用于记录检查过的人
while search_queue: #如果队列不为空
person = search_queue.popleft() #取出队列中排头第一人
if person not in searched: #如果person不在已检查过的人
if person_is_seller(person): #如果满足芒果销售商的判断函数
print(person + " is a mango seller!") #打印此人是芒果销售商
return True
else:
search_queue += graph[person] #如果查找的人不是芒果销售商,则将此人的朋友加入搜索队列
searched.append(person) #将此人加入已检查的数组中
return False #如果执行此句,说明队列为空,说明队列中没人是芒果销售商
search("you")
运行结果: