《算法图解》学习笔记—第6章 广度优先搜索

前言

广度优先搜索(breadth-first search,BFS)是一种图算法。广度优先搜索可以找出两样东西之间的最短距离,使用广度优先搜索可以:

  • 编写国际跳棋AI,计算最少走多少步就可获胜;
  • 编写拼写检查器,计算最少编辑多少个地方就可将错拼的单词改成正确的单词,如将READED改为READER需要编辑一个地方;
  • 根据你的人际关系网络找到关系最近的医生。

最短路径问题(shorterst-path problem)。你经常要找出最短路径,这可能是前往朋友家的最短路径,也可能是国际象棋中把对方将死的最少步数。解决最短路径问题的算法被称为广度优先搜索。
在这里插入图片描述
要确定如何从双子峰前往金门大桥,需要两个步骤。
(1) 使用图来建立问题模型。
(2) 使用广度优先搜索解决问题。

6.1 图简介

图由节点(node)和边(edge)组成。一个节点可能与众多节点直接相连,这些节点被称为邻居。
在这里插入图片描述

6.2 广度优先搜索

广度优先搜索是一种用于图的查找算法。
实例:假设你经营着一个芒果农场,需要寻找芒果销售商,以便将芒果卖给他。在Facebook,你与芒果销售商有联系吗?为此,你可在朋友中查找。
在这里插入图片描述

队列

你需要按加入顺序检查搜索列表中的人,否则找到的就不是最短路径,因此搜索列表必须是队列。
队列只支持两种操作:入队和出队。队列是一种先进先出(First In First Out,FIFO)的数据结构,而栈是一种后进先出(Last InFirst Out,LIFO)的数据结构。
在这里插入图片描述

有向图、无向图

有向图(directed graph)中的关系是单向的。无向图(undirected graph)没有箭头,直接相连的节点互为邻居。例如,下面两个图是等价的。
在这里插入图片描述
树是一种特殊的图,其中没有往后指的边。
在这里插入图片描述

实现算法

算法的工作原理:
(对于检查过的人,务必不要再去检查,否则可能导致无限循环。)
在这里插入图片描述

from collections import deque
search_queue = deque()    #创建一个队列
search_queue += graph["you"]#将你的邻居都加入到这个搜索队列中

def 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 False

def person_is_seller(name):
return name[-1] == 'm' #示例中假设“函数检查人的姓名以m结尾就是芒果销售商”

运行时间

如果你在你的整个人际关系网中搜索芒果销售商,就意味着你将沿每条边前行(记住,边是从一个人到另一个人的箭头或连接),因此运行时间至少为O(边数)。
你还使用了一个队列,其中包含要检查的每个人。将一个人添加到队列需要的时间是固定的,即为O(1),因此对每个人都这样做需要的总时间为O(人数)。所以,广度优先搜索的运行时间为O(人数 + 边数),这通常写作O(V + E),其中V为顶点(vertice)数,E为边数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值