当前位置: 首页 > news >正文

算法图解之广度优先算法

一、用途

广度优先算法是为了解决两样东西之间的最短距离,其中最短距离的含义很多,如:

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

二、图

图由节点和边组成,模拟一组链接。

 

 三、广度优先搜索

应用场景

  • 从节点A出发,有前往节点B的路径吗?
  • 从节点A出发,前往节点B的哪条路径最短?

问题:你经营着一个芒果农场,你要找一个芒果销售商并把芒果卖给他。

解决思路:你需要优先从你的朋友中开始找,朋友中没有,再从朋友的朋友中找,在找完所有朋友之前,不去找朋友的朋友。以此类推。如下图所示:

 

这就需要按顺序进行添加,并按顺序进行查找,有一种数据结构可以实现这个目的,就是队列

 

四、队列(Queues)

队列的工作原理就和在医院排队挂号一张,排在前面的先挂号。

队列是一种先进先出(First In First Out)的数据结构,而栈是一种后进先出(Last In First Out,LIFO)的数据结构。

队列图示:

 

 

五、有向图和无向图

 

有箭头指向自己,但是没有从自己指向其他人的箭头,这被称为有向图(directed graph),其中的关系是单向的。 (Anuj、Peggy、Thom、Jonny)

直接相连的节点互为邻居,被称为无向图。

 

六、实现算法

from collections import deque

graph = {}
graph['you'] = ['alices', 'bobs', 'claires']
graph['bobs'] = ['anujs', 'peggys']
graph['alices'] = ['peggys']
graph['claires'] = ['thoms', 'jonnys', 'jack']
graph['anujs'] = []
graph['peggys'] = []
graph['thoms'] = []
graph['jonnys'] = []
graph['jack'] = ['lucy', 'mango_andrew']
graph['lucy'] = []
graph['mango_andrew'] = []


def person_is_seller(name):
    return 'mango' in name


def search(name):
    search_queue = deque()
    search_queue += graph[name]
    searched = []

    while search_queue:
        person = search_queue.popleft()

        if person not in searched:
            if person_is_seller(person):
                print(person[6:] + ' is a mongo seller')
                return True
            else:
                search_queue += graph[person]
                searched.append(person)
    print('Not find mango seller')
    return False


search('you')

 

顺便提一下,字典这么写是为了看起来更清晰,它的添加顺序对结果是没有影响的,因为散列表是无序的。

graph['you'] = ['alices', 'bobs', 'claires']
graph['bobs'] = ['anujs', 'peggys']

# 写成下面这样对结果一点影响都没有
graph['bobs'] = ['anujs', 'peggys']
graph['you'] = ['alices', 'bobs', 'claires']

 

 

 

 

七、运行时间

你在整个人际关系网中搜索芒果销售商,就意味着你需要沿每条边前行(一个人到另一个人的箭头),时间至少为O(边数)。将每一个人添加到队列的时间是O(1),因此广度搜索的运行时间为O(人数 + 边数),通常写作O(V+E),其中V为定点(vertice),E为边数。

转载于:https://www.cnblogs.com/lshedward/p/10480342.html

相关文章:

  • uboot内存布局(平台imx6 uboot2016)
  • 【干货】Kafka实现淘宝亿万级数据统计(下)
  • 绑定hover事件
  • 腾讯58篇论文入选CVPR 2019,涵盖视觉对抗学习等方向
  • E.华华给月月准备礼物
  • 【NOI2018模拟】Yja
  • npm install -g react-native-cli 报错:errno -4048
  • 如何在GitHub上创建个人博客
  • layDay日期格式不合法报错解决
  • 静态路由实验
  • 第2部分 Elasticsearch查询-请求体查询、排序
  • 利用Python绘制一个正方形螺旋线
  • OPPO大数据平台运营研发实践分享
  • 没有一个技术天生完美,MongoDB十年发展全纪录
  • 嵌入式软件架构设计
  • Google 是如何开发 Web 框架的
  • 【跃迁之路】【733天】程序员高效学习方法论探索系列(实验阶段490-2019.2.23)...
  • 2017年终总结、随想
  • JavaScript 基础知识 - 入门篇(一)
  • Javascript基础之Array数组API
  • JavaScript设计模式与开发实践系列之策略模式
  • Java方法详解
  • jquery ajax学习笔记
  • js ES6 求数组的交集,并集,还有差集
  • Laravel Mix运行时关于es2015报错解决方案
  • mongo索引构建
  • nodejs调试方法
  • RedisSerializer之JdkSerializationRedisSerializer分析
  • Spark学习笔记之相关记录
  • SpiderData 2019年2月25日 DApp数据排行榜
  • Vue.js 移动端适配之 vw 解决方案
  • Vue.js-Day01
  • win10下安装mysql5.7
  • 半理解系列--Promise的进化史
  • 得到一个数组中任意X个元素的所有组合 即C(n,m)
  • 干货 | 以太坊Mist负责人教你建立无服务器应用
  • 猴子数据域名防封接口降低小说被封的风险
  • 简析gRPC client 连接管理
  • 模仿 Go Sort 排序接口实现的自定义排序
  • 日剧·日综资源集合(建议收藏)
  • 如何优雅的使用vue+Dcloud(Hbuild)开发混合app
  • 山寨一个 Promise
  • 删除表内多余的重复数据
  • 深入体验bash on windows,在windows上搭建原生的linux开发环境,酷!
  • 微信小程序:实现悬浮返回和分享按钮
  • 我的zsh配置, 2019最新方案
  • AI算硅基生命吗,为什么?
  • Nginx实现动静分离
  • 教程:使用iPhone相机和openCV来完成3D重建(第一部分) ...
  • ​​​​​​​GitLab 之 GitLab-Runner 安装,配置与问题汇总
  • #LLM入门|Prompt#1.7_文本拓展_Expanding
  • $分析了六十多年间100万字的政府工作报告,我看到了这样的变迁
  • (06)金属布线——为半导体注入生命的连接
  • (22)C#传智:复习,多态虚方法抽象类接口,静态类,String与StringBuilder,集合泛型List与Dictionary,文件类,结构与类的区别
  • (C++)八皇后问题