双向BFS搜索和A*算法

2023-11-09

双向BFS适合给出起点和终点,求最短路径的问题

分别从起点和终点扩展,找交点。每次选择待扩展节点少的那个方向进行扩展,一次扩展一层。

扩展一个节点的时候,如果节点也在另一个方向的待扩展队列里,找到交点。

int doubleBFS(vector<vector<int>> &G, int start, int end) {
	vector<vector<bool>> marked(2, vector<bool>(G.size()));//dead and to-be-expanded nodes
	queue<int> q[2]; //newly expanded nodes, to be expanded
	int level[2] {0, 0}; //how many levels that has finished expanding
	q[0].push(start), marked[0][start] = true, marked[1][end] = true, q[1].push(end);
	//expand one level. choose next direction at end: whose to-be-expand list is smaller
	for (int t = 0; q[t].size() > 0; ++level[t], t = q[0].size() <= q[1].size() ? 0 : 1) {
		for (int sz = q[t].size(), i = 0; i < sz; ++i) {
			int v = q[t].front(); q[t].pop();
			//in the other direction's queue, intersection  found
			if (marked[!t][v]) return level[0] + level[1] + 1;
			for (int w : G[v]) {
				if (!marked[t][w]) {
					marked[t][w] = true;
					q[t].push(w);
				}
			}
		}
	}
	return -1; //the given nodes are not connected
}



具体求出路径

vector<int> doubleBFS(vector<vector<int>> &G, int start, int end) {
	vector<vector<bool>> marked(2, vector<bool>(G.size())); //dead and to-be-expand nodes
	vector<int> prev[2] {vector<int>(G.size()), vector<int>(G.size())}; //predecessor
	queue<int> q[2]; //newly expanded nodes, to be expanded
	q[0].push(start), marked[0][start] = true, marked[1][end] = true, q[1].push(end);
	//expand one level, determine next direction at end: whose queue is smaller
	for (int t = 0; q[t].size() > 0; t = q[0].size() <= q[1].size() ? 0 : 1) {
		for (int sz = q[t].size(), i = 0; i < sz; ++i) {
			int v = q[t].front(); q[t].pop();
			// in the other direction's to-be-extended list, intersection found
			if (marked[!t][v]) {
				deque<int> path;
				for (int x = v; x != start; x = prev[0][x]) path.push_front(prev[0][x]);
				path.push_back(v);
				for (int x = v; x != end; x = prev[1][x]) path.push_back(prev[1][x]);
				return vector<int>(path.begin(), path.end());
			}
			for (int w : G[v]) {
				if (!marked[t][w]) {
					marked[t][w] = true;
					prev[t][w] = v;
					q[t].push(w);
				}
			}
		}
	}
	return {}; //the given nodes are not connected
}


BFS,DFS,A*分别是三种不同的搜索(遍历)顺序:

BFS:宽度优先

DFS:深度优先

A* :  估价优先

A*是带一点启发式的搜索,对新扩展出来的节点用估价函数 f(v) = g(v) + h(v)进行估价,按估价排序,然后选择下一个扩展节点。A*是dfs、bfs之外的另一种遍历顺序——按估价。对应的容器分别是stack, queue, priority_queue。

BFS,DFS,A*只是搜索顺序不同,并没有排除、丢弃任何节点,都是O(n)的,只是期望目标节点尽可能排在前面。 还有一些搜索是可以排除、丢弃一部分节点的搜索,比如局部择优搜索、二分搜索。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

双向BFS搜索和A*算法 的相关文章

  • 子串/子段问题总结

    1 一般子串问题 求一个串中满足某种条件的子串 1 如果所求子串的条件是一个值 比如sum 则考虑子段问题 注意这样一个性质 子段 前缀差 子段和 前缀和的差 vector
  • 爬虫中网页分析的几种技术

    一般来说我们只抓取网页中的特定数据 比如抓取某人所有的blog 我们就只关心list 页面中文章列表那部分的链接和title 有几种技术可以用来分析网页 1 正则匹配 2 一般字符串匹配content substring pattern s
  • 自己动手写一个key value store

    一涉及到persistent 哪怕只是最基本的需求 很多人都会依赖数据库 或是其他现成的库或工具 确实 对于文件 大部分人很少直接打交道 或者只是诸如整体反序列化 序列化 按行读取 append new line等有限的操作 一个persi
  • 中缀表达式求值问题

    1 有无括号 2 一种优先级运算符 只有 或 还是2种 和 都有 3 求逆波兰序列 求值 求表达式树 两种思路 1 分治 求值 和求表达式树都可以用 nlogn 1 先去掉冗余括号 两边最外面的 如 1 1 2 如果有的话 找到优先级最小的
  • 背包问题,硬币问题

    至少有4种背包问题 1 01背包 2 部分背包 3 完全背包 4 多重背包 只有部分背包是个贪心问题 其他的都是以01背包为基础的动归问题 部分背包问题 把物品按价值密度从大到小排序 W i V i 然后从第一种物品开始 尽可能多拿当前物品
  • 还是搜索、索引的问题

    搜索要弄清2个基本问题 1 要搜索出什么类型的entity 2 entity的哪个方面 维度和关键词发生关联的 一般来说可以有多个角度link到entity 一个entity支持多个索引 可以从不同的column检索 对于 web sear
  • merge sort 一些变种、应用

    1 逆序对数目 分治公式 总的逆序对个数 前半部分逆序对个数 后半部分逆序对个数 merge时候每取一次后半部分的数 累加一次前半部分剩余的数的个数 int countInvertion vector
  • 最大公约数,最小公倍数,素数等问题

    1 两个数的 最小公倍数 等于两个数的乘积除以最大公约数 scm a b a b gcd a b 所以主要是最大公约数问题 gcd 问题 辗转相除法 依据就是欧几里得定理 gcd a b gcd b a b def gcd a b whil
  • 算法的三种练习

    除了具体写代码 做这些练习 1 循环不变式 用循环不变式去解释算法 2 递归 动归的 递推式 3 搜索问题的隐式图构造 隐式树还是图 一个前驱 多个前驱 点是什么 边是什么 怎么扩展
  • 最少砝码问题(用一部分数的和/差表示区间上所有的整数)

    问题1 需要表示 1 N 的所有重量 最少需要多少砝码 答案 需要 1 2 4 ceiling logN 每个砝码代表二进制数的一位 N有ceiling logN 个二进制位 问题2 需要表示 1 N 的所有重量 手头已有一些砝码 问 怎样
  • 一个完整的语法分析、词法分析例子——Universal Pasrser

    需求 用户用formal notation指定语法 词法 然后可以匹配相应的文本 用法类似正则表达式 只需给出formal notation 不需要为每一种格式的文本单独写匹配器 formal notation主要是3个部分 1 BNF 列
  • 再谈type ahead 问题

    问题 给定一个词典 包括一些词和其出现的频率 实现type ahead功能 要求用户每键入一个字符 下拉框显示以当前输入为前缀的前10个最热门的词 解法1 用不带data的Trie data仅仅是词频 实时查询法 需要实时的去build h
  • 路径搜索问题

    之前碰到的很多问题都可以归结为路径搜索问题 就是求两点之间的路经 1 是否存在路径 2 求任意一条路径 3 求所有路径 求是否有路径和任意一条路径的时候 和正常遍历一样 一个点被mark之后不再访问 因为如果这个结点到终点有路径 之前就应该
  • 双向BFS搜索和A*算法

    双向BFS适合给出起点和终点 求最短路径的问题 分别从起点和终点扩展 找交点 每次选择待扩展节点少的那个方向进行扩展 一次扩展一层 扩展一个节点的时候 如果节点也在另一个方向的待扩展队列里 找到交点 int doubleBFS vector
  • 大数据问题汇总

    1最基本的 一个数据流 文件 求top k biggest solution 维护大小为K的最小堆 和堆顶比 大于堆顶的加入堆 堆顶相当于准入门槛 如果size 超过K 移除堆顶 vector
  • 打表法经典2题:小于n的质数和第k个丑数

    1 求小于n的所有质数 1 开一个大小为n的bool数组A 下标代表整数 值true代表被mark过 有因子 非素数 2 i 从 2开始到n 1 如果A i 没被mark A i 就是质数 然后mark有A i 因子的数 2 A i 3 A
  • 再谈缓存

    凡是涉及管理数据的系统 都可以用图书馆来考虑 都要面临图书的位置查找和实际摆放两个问题 对应的两大组件就是就是index store 所有的数据管理系统都包含这两部分 缓存从过期又什么触发的角度分为容量触发和时间触发 容量触发 就是缓存满了
  • 有限自动机总结

    有限自动机A用来识别字符串 它由5部分组成 1 alphabet 字符集 2 states 状态集合 3 init 初始状态 4 trans s ch 状态转移函数 5 end 可接受state 集合 A str true的意思是 A可以接
  • 递归、加法原理,如何分解问题(独立且完备的划分)

    加法原理适用于做一件事有n种独立不相交且完备的方向 每个方向上有ai种方案 则总的方案数就是 a1 a2 an 例题 把n个数分为k个非空子集 有多少种分法 分解问题 第一个集合里放多少个数把原问题的解分成了独立且完备的若干方向 分别解每个
  • 数组双指针法汇总

    指针移动方向 相向夹逼 同向移动 维护的是一个区间还是只是关心指针指向的两个元素 同向移动的 维护一个区间的双指针法即滑动窗口法 2Sum 排序后两头往中间夹逼的双指针法 指针为什么可以不回退 即为什么可以i只 j只 当A i A j

随机推荐

  • 利用短时傅里叶变换(STFT)对信号进行时频谱分析和去噪声

    利用短时傅里叶变换 STFT 对信号进行时频谱分析和去噪声 1 背景 傅里叶变换 TF 对频谱的描绘是 全局性 的 不能反映时间维度局部区域上的特征 人们虽然从傅立叶变换能清楚地看到一整段信号包含的每一个频率的分量值 但很难看出对应于频率域
  • 基于Spring Gateway路由判断器实现各种灰度发布场景

    文章目录 1 灰度发布实现 1 1 按随机用户的流量百分比实现灰度 1 2 按人群划分实现的灰度 1 2 1 通过Header信息实现灰度 1 2 2 通过Query信息实现灰度 1 2 3 通过RemoteAdd判断来源IP实现灰度 2
  • django中models field详解

    本文参考自 django官方文档models field 在model中添加字段的格式一般为 field name field type field options 一 field options 所有字段共用 1 null 默认为Fals
  • 滤波器拓扑结构:Sallen-key和Multiple Feedback

    在一些关于滤波器设计的地方 总可以看到Sallen key和Multiple Feedback这两个词组 但不清楚什么意思 查了查资料 顺带在此处记录一下 Sallen key 麻省理工学院林肯实验室的R P Sallen and E L
  • Android Studio第一次安装虚拟机时报错Emulator:ERROR: Unknown AVD name[ ], use -list-avds to see valid list.

    安装完虚拟机后点击启动报错 虚拟化已开启 解决办法 1 修改环境变量ANDROID SDK HOME路径指到platforms路径下 例如 D androidSDK platforms 2 重启Android Studio 3 重新安装虚拟
  • 学习笔记:CentOS7安装Docker

    一 检查CentOS 系统的内核版本 Docker 要求 CentOS 系统的内核版本高于 3 10 通过 uname r 命令查看当前的内核版本 二 检查并清除系统残余项 并安装Docker依赖环境 1 卸载Docker 可选 如果之前安
  • 百度新闻资讯类信息爬虫--统计一年内关键词新闻的条数

    背景 通过百度词条搜索 来查找300个关键词 在一年内发布新闻的条数 最终效果实现如下 实现思路 实现思路依然是 先根据多页的url 来找到规律 构建起一页的url def format url url params dict None g
  • [转]信息安全相关理论题(三)

    21 静态分析是运行程序后进行调试 A 对 B 错 您的答案 标准答案 B 22 安卓反编译后会出现 符号字节码表示是匿名内部类 A 对 B 错 您的答案 标准答案 A 23 反编译安卓应用后 一般应该先查看哪一个smali文件的代码 A
  • JAVA反射机制及应用场景

    往往当我们面对一项新的知识时 我们往往需要知道三个方面 它是什么 它能做什么 它比原有知识强在哪里 我们该怎么使用它 当你能够解决这些问题时 便意味着你已经对这项知识入门了 一 是什么 Java Reflaction in Action有这
  • TOGAF9.2第I部分 第2章核心概念

    本章提供的核心概念适用TOGAF标准 2 1 什么是TOGAF标准 TOGAF标准是一个架构框架 它提供了协助接受 生产 使用和维护企业架构的方法和工具 它基于支持最佳实践和可重用的现有架构资产集的迭代过程模型 2 2 TOGAF标准中的架
  • 学习笔记——机器学习(第二章)

    机器学习 第二章 还有很多细节部分 我正在完善和补充 Emmm 若有不足 还请包涵 1 2 3 4 5 6 7 8 9 10 11 12 13 14
  • 致性哈希算法的优化----关于如何保正在环中增加新节点时,命中率不受影响

    背景 09年初 我们做了一个memcached的智能客户端库 业务只要将这个库链上 就能跟memcached服务器通信 并且实现了一致性哈希的分布式算法 后端memcached服务器可以无限制扩展 而且客户端能对memcached做自动故障
  • cmake系列-动态库的生成与链接

    运行系统 Ubuntu20 04 运行环境 python 2 7 17 系统不一样 遇到的问题可能不一样 该方法不一定见效 问题描述 工作中时常需要调用同事写的 so文件作为一些功能的接口 那么如何将cmake文件进行动态库生成和调用呢 实
  • redissonclient类_Redisson入门教程

    Redisson入门 Author RickyDate 2017 04 24 Redisson概述 Redisson是架设在Redis基础上的一个Java驻内存数据网格 In Memory Data Grid 充分的利用了Redis键值数据
  • MySQL数据库学习(保姆级教程)(1.7W字)

    1 初识MySQL JavaEE 企业级Java开发 Web 前端 页面 展示 数据 后台 连接点 连接数据库JDBC 链接前端 控制 控制视图跳转 和给前端传递数据 数据库 存数据 Txt Excel Word 只会写代码 学好数据库 基
  • buuctf web 前5题

    目录 一 极客大挑战 2019 EasySQL 总结 二 极客大挑战 2019 Havefun 总结 三 HCTF 2018 WarmUp 总论 四 ACTF2020 新生赛 Include 总结 五 ACTF2020 新生赛 Exec 总
  • 电脑cpu排名_2019年12月最新CPU天梯图 CPU性能排行榜

    参考国外评测机构PassMark的数据 下面排行榜比较了笔记本和台式电脑CPU的性能 截止更新时间为2019年12月5日 下方为排名前30的CPU天梯图 为方便大家查看更多CPU具体型号的排名和评分 请看天梯图后面的图表 注 电脑端可以使用
  • 投影变换 到 uv坐标 xy/w ---齐次坐标

    float3 vScreenPos In ClipPos xyz vScreenPos In ClipPos w vScreenPos xy 1 f vScreenPos xy 0 5f vScreenPos y 1 f vScreenPo
  • word 插入 高亮代码

    word 插入高亮代码 方法1 直接复制 IDE 中的内容 优 随时随地复制 保留vscode格式 缺 其他IDE的格式可能就不好看了 方法2 代码复制到网站 highlightcode com 高亮后再复制到word 缺 高亮做的不好看
  • 双向BFS搜索和A*算法

    双向BFS适合给出起点和终点 求最短路径的问题 分别从起点和终点扩展 找交点 每次选择待扩展节点少的那个方向进行扩展 一次扩展一层 扩展一个节点的时候 如果节点也在另一个方向的待扩展队列里 找到交点 int doubleBFS vector