《算法图解》第六章 广度优先搜索

来源:互联网 发布:万能转换软件 编辑:程序博客网 时间:2024/06/07 00:41

第六章 广度优先搜索 breadth first search BFS

广度优先搜索让你能够找出两样东西之间的最短距离,不过最短距离的含义有很多!使用广度优先搜索可以:
编写国际跳棋AI,计算最少走多少步就可获胜;
编写拼写检查器,计算最少编辑多少个地方就可将错拼的单词改成正确的单词,如将READED改为READER需要编辑一个地方;
根据你的人际关系网络找到关系最近的医生。


6.1图简介

6.2图是什么

6.3广度优先搜索

6.4实现图

6.5实现算法

6.1图简介及6.2图


你从一个城市到其他城市,可能有很多出行方案,如何选择一条路径最短的呢?

引出图--图论里的算法

把各个城市都看成一个点,各个点之间连线,且是有向的---有向图

6.3广度优先搜索

可以找到A到B的路径,且可以找到最短的路径

6.3.1查找最短路径

引入找芒果商的问题,在你的朋友中搜索,如果么有的话再从朋友的朋友搜索,直到找芒果商或者全部找完没有芒果商为止

6.3.2队列

先进先出,入列和出队

栈是后进先出

这里的算法和队列有什么关系呢?

6.4实现图

怎么从一张图转为算法呢---需要散列表来描述图上各个节点的关系

6.5实现算法及运行时间

查找周围的人有没有芒果商贩

实现算法---先把伪代码写出来

1.首先把图”画“(用代码表示)出来,用散列表进行表示

graph={}---散列表或者dict[]

graph["a"]=["b","c","d"]---标红是因为这用的是数组[]和不是{}这句代码表明,a和bcd相连---无向图也可以这么做吧?

2.把第一轮要检查的人(也就是自己的朋友)排成一个队列,进行检查,如果是芒果商,则算法停止,如果不是芒果商,则朋友的朋友列入队列中

3.如果第一轮没有检查出芒果商,则对新加入队列的进行检查,如此反复进行

具体的问题如下


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 person_is_seller(name):    return name[-1]=='m'    from collections import dequedef search(name):    search_queue = deque()    search_queue += graph[name]    searched = []    while search_queue:        person = search_queue.popleft()        if not person in searched:            if person_is_seller(person):                print(person+' is a mango seller')                return True            else:                search_queue += graph[person]                searched.append(person)    return Falseprint(search("you"))

1.deque 的用法 from collection import deque

2.search("you")里面不是写入graph,而是起点 

运行时间

你在朋友关系网中搜寻芒果商,对每个朋友进行搜索,就是对你到朋友的每条边进行搜索,所以运行时间是O(边数),又把这些人排成队列,对每个人进行判断,运行时间是O(人数),所以总的时间是O(人数+边数),在图里就是O(边数+点数)O(E+V)

6.6小结

广度优先搜索指出是否有从AB的路径。
如果有,广度优先搜索将找出最短路径。
面临类似于寻找最短路径的问题时,可尝试使用图来建立模型,再使用广度优先搜索来解决问题。
有向图中的边为箭头,箭头的方向指定了关系的方向,例如,ramaadit表示ramaadit钱。
无向图中的边不带箭头,其中的关系是双向的,例如,ross - rachel表示“rossrachel约会,而rachel也与ross约会”。
队列是先进先出(FIFO)的。
栈是后进先出(LIFO)的。
你需要按加入顺序检查搜索列表中的人,否则找到的就不是最短路径,因此搜索列表必须是队列。
对于检查过的人,务必不要再去检查,否则可能导致无限循环。