双向宽度优先搜索 (Bidirectional BFS) 算法适用于如下的场景:

  1. 无向图
  2. 所有边的长度都为 1 或者长度都一样
  3. 同时给出了起点和终点

以上 3 个条件都满足的时候,可以使用双向宽度优先搜索来求出起点和终点的最短距离。

算法描述

双向宽度优先搜索本质上还是BFS,只不过变成了起点向终点和终点向起点同时进行扩展,直至两个方向上出现同一个子节点,搜索结束。我们还是可以利用队列来实现:一个队列保存从起点开始搜索的状态,另一个保存从终点开始的状态,两边如果相交了,那么搜索结束。起点到终点的最短距离即为起点到相交节点的距离与终点到相交节点的距离之和。

Q.双向BFS是否真的能提高效率?
假设单向BFS需要搜索 N 层才能到达终点,每层的判断量为 X,那么总的运算量为 X ^ NXN. 如果换成是双向BFS,前后各自需要搜索 N / 2 层,总运算量为 2 * X ^ {N / 2}2∗XN/2。如果 N 比较大且X 不为 1,则运算量相较于单向BFS可以大大减少,差不多可以减少到原来规模的根号的量级。

from collections import deque

def doubleBFS(start, end):
if start == end:
return 1 # 分别从起点和终点开始的两个BFS队列
startQueue, endQueue = deque(), deque()
startQueue.append(start)
endQueue.append(end)
step = 0 # 从起点开始和从终点开始分别访问过的节点集合
startVisited, endVisited = set(), set()
startVisited.add(start)
endVisited.add(end)
while len(startQueue) and len(endQueue):
startSize, endSize = len(startQueue), len(endQueue)
# 按层遍历
step += 1
for _ in range(startSize):
cur = startQueue.popleft()
for neighbor in cur.neighbors:
if neighbor in startVisited: # 重复节点
continue
elif neighbor in endVisited: # 相交
return step
else:
startVisited.add(neighbor)
startQueue.append(neighbor)
step += 1
for _ in range(endSize):
cur = endQueue.popleft()
for neighbor in cur.neighbors:
if neighbor in endVisited:
continue
elif neighbor in startVisited:
return step
else:
endVisited.add(neighbor)
endQueue.append(neighbor) return -1

  

学习建议

Bidirectional BFS 掌握起来并不是很难,算法实现上稍微复杂了一点(代码量相对单向 BFS 翻倍),掌握这个算法一方面加深对普通 BFS 的熟练程度,另外一方面,基本上写一次就能记住,如果在面试中被问到了如何优化 BFS 的问题,Bidirectional BFS 几乎就是标准答案了。

参考资料

https://www.geeksforgeeks.org/bidirectional-search

应用例题

Shortest Path in Undirected Graph
Knight Shortest Path
Knight Shortest Path II

BFS算法的优化 双向宽度优先搜索的更多相关文章

  1. 【算法入门】广度/宽度优先搜索(BFS)

    广度/宽度优先搜索(BFS) [算法入门] 1.前言 广度优先搜索(也称宽度优先搜索,缩写BFS,以下采用广度来描述)是连通图的一种遍历策略.因为它的思想是从一个顶点V0开始,辐射状地优先遍历其周围较 ...

  2. 算法基础⑦搜索与图论--BFS(宽度优先搜索)

    宽度优先搜索(BFS) #include<cstdio> #include<cstring> #include<iostream> #include<algo ...

  3. 层层递进——宽度优先搜索(BFS)

    问题引入 我们接着上次“解救小哈”的问题继续探索,不过这次是用宽度优先搜索(BFS). 注:问题来源可以点击这里 http://www.cnblogs.com/OctoptusLian/p/74296 ...

  4. 【BFS宽度优先搜索】

    一.求所有顶点到s顶点的最小步数   //BFS宽度优先搜索 #include<iostream> using namespace std; #include<queue> # ...

  5. 搜索与图论②--宽度优先搜索(BFS)

    宽度优先搜索 例题一(献给阿尔吉侬的花束) 阿尔吉侬是一只聪明又慵懒的小白鼠,它最擅长的就是走各种各样的迷宫. 今天它要挑战一个非常大的迷宫,研究员们为了鼓励阿尔吉侬尽快到达终点,就在终点放了一块阿尔 ...

  6. 挑战程序2.1.5 穷竭搜索>>宽度优先搜索

    先对比一下DFS和BFS         深度优先搜索DFS                                   宽度优先搜索BFS 明显可以看出搜索顺序不同. DFS是搜索单条路径到 ...

  7. [宽度优先搜索] FZU-2150 Fire Game

    Fat brother and Maze are playing a kind of special (hentai) game on an N*M board (N rows, M columns) ...

  8. 宽度优先搜索--------迷宫的最短路径问题(dfs)

    宽度优先搜索运用了队列(queue)在unility头文件中 源代码 #include<iostream>#include<cstdio>#include<queue&g ...

  9. "《算法导论》之‘图’":深度优先搜索、宽度优先搜索(无向图、有向图)

    本文兼参考自<算法导论>及<算法>. 以前一直不能够理解深度优先搜索和广度优先搜索,总是很怕去碰它们,但经过阅读上边提到的两本书,豁然开朗,马上就能理解得更进一步. 下文将会用 ...

随机推荐

  1. Redis常见场景解析

    一 前言 Redis是一个key-value存储系统,现在在各种系统中的使用越来越多,大部分情况下是因为其高性能的特性,被当做缓存使用,这里介绍下Redis经常遇到的使用场景. 二 Redis特性 一 ...

  2. Gamma阶段发布说明

    访问我们 公课网 Gamma新增功能和缺陷修复 Gamma新增功能 增加找回密码功能~妈妈再也不用担心我的密码忘掉了. 增加管理员功能,有权删除评论并通知用户. 增加信箱功能,评论被管理员删除后会得到 ...

  3. 【操作系统之九】Linux常用命令之netstat

    一.概念netstat命令用于显示与IP.TCP.UDP和ICMP协议相关的统计数据,一般用于检验本机各端口的网络连接情况.netstat是在内核中访问网络及相关信息的程序,它能提供TCP连接,TCP ...

  4. 《Linux就该这么学》自学笔记_ch22_使用openstack部署云计算服务环境

    <Linux就该这么学>自学笔记_ch22_使用openstackb部署云计算服务环境 文章主要内容: 了解云计算 Openstack项目 服务模块组件详解 安装Openstack软件 使 ...

  5. jquery插件实现瀑布流

    jquery插件实现瀑布流<!DOCTYPE html><html lang="en"><head> <meta charset=&quo ...

  6. Kafka部署篇

    目录 安装 下载与安装 配置 启停操作 验证 基本操作 创建topic 列出现有的topic 查看topic的详细信息 增加topic的partition数量 修改一个topic的副本数 删除一个to ...

  7. git在使用push指令的时候产生的错误

    一.问题我们在使用git指令的时候往往会出现如下错误. $ git push -u origin master To https://github.com/pzq7025/ss-fly.git ! [ ...

  8. docker 安装tomcat容器和mysql容器

    1. docker pull mysql:5.6 2.docker run -p 3306:3306 --name mysql -v /data/mysql/conf:/etc/mysql/conf. ...

  9. 2019 珍岛java面试笔试题 (含面试题解析)

      本人5年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.珍岛等公司offer,岗位是Java后端开发,因为发展原因最终选择去了珍岛,入职一年时间了,也成为了面试官,之 ...

  10. 安装fastnlp

    直接 pip install fastnlp 如果出现 torch的安装报错,可能与操作系统及 CUDA 的版本相关.直接上pytorch 的官网 https://pytorch.org/get-st ...