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

软件环境:Python 3.7.0b4

一、算法描述

假设你经营着一家芒果农场,需要寻找芒果销售商,以便将芒果卖给他。为此,我们可以通过广度优先搜索算法,在朋友中查找出符合条件的芒果销售商。

广度优先搜索是一种用于图的查找算法,可帮助我们回答两类问题:

  • 第一类问题:从节点A出发,有前往节点B的路径吗?(在你的人际关系网中,有芒果销售商吗?)
  • 第二类问题:从节点A出发,前往节点B的哪条路径最短?(哪个芒果销售商与你的关系最近?)

二、实现图

将下列关系图用散列表实现

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"] = []

注:Anuj、Peggy、Thom和Jonny都没有邻居,这是因为虽然有指向他们的箭头,但没有从他们出发指向其他人的箭头。这被称之为有向图(directed graph),其中的关系是单向的。而无向图(undirected graph)没有箭头,直接相连的节点互为邻居。

三、实现算法

概述广度优先搜索算法的工作原理:

完整实现代码如下:

from collections import deque

def person_is_seller(name):
      return name[-1] == '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] # 将你的邻居都加入到这个搜索队列中
    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 # 队列中没人是芒果销售商

search("you")

四、小结

  • 队列是先进先出的。
  • 栈是后进先出的。
  • 你需要按加入顺序检查搜索列表中的人,否则找到的就不是最短路径,因此搜索列表必须是队列。
  • 对于检查过的人,务必不要再去检查,否则可能导致无限循环。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏不想当开发的产品不是好测试

查看占用内存多的进程

ps -e  -o "%C  : %p : %z : %a"|sort -k5 -nr|head -10 -e,显示出所有的进程 -o,格式化输出 CODE  ...

1847
来自专栏机器学习与自然语言处理

图的遍历之深度优先搜索(DFS)

深度优先搜索(depth-first search)是对先序遍历(preorder traversal)的推广。”深度优先搜索“,顾名思义就是尽可能深的搜索一个...

20410
来自专栏深度学习与计算机视觉

算法-两个栈实现队列

题目: 用两个栈实现一个队列。队列的声明如下,请实现它的两个函数appendTail和deleteHead,分别完成在队列尾部插入结点和在队列头部删除结点的...

19410
来自专栏程序员宝库

PHP 中被忽略的性能优化利器:生成器

如果是做Python或者其他语言的小伙伴,对于生成器应该不陌生。但很多PHP开发者或许都不知道生成器这个功能,可能是因为生成器是PHP 5.5.0才引入的功能,...

2976
来自专栏.net core新时代

我是怎么使用最短路径算法解决动态联动问题的

  省市县三级联动问题相信大家都耳熟能详了,选择市下拉选项依赖于省,同样的选择县下拉选项依赖于市。把省市县抽象成三个节点A(省),B(市),C(县),它们的关系...

1969
来自专栏我是业余自学C/C++的

栈(stack)是一种特殊的线性表,其插入(也称入栈或压栈)和删除(也称出栈或弹栈)操作都在表的同一端进行。这一端被称为栈顶(top)另一端称为栈底端(bott...

581
来自专栏开发与安全

2014.03.16 网易游戏TTT计划实习生笔试题

注:这份试题是本人事后回忆的,题目可能会有出入,且给出的答案不一定正确,仅供参考,欢迎指正错误。 前面这些题是试卷的第I部分,试卷上面说第一部分达不到基本线直接...

1879
来自专栏章鱼的慢慢技术路

《算法图解》第六章笔记

1425
来自专栏海天一树

约瑟夫环的三种解法

约瑟夫环(Josephus)问题是由古罗马的史学家约瑟夫(Josephus)提出的,他参加并记录了公元66—70年犹太人反抗罗马的起义。约瑟夫作为一个将军,设法...

862
来自专栏智能算法

Python学习(二)---- 字符串操作、列表字典及深浅拷贝等

https://blog.csdn.net/fgf00/article/details/52061971

822

扫码关注云+社区