启发式搜索: A*算法
启发式搜索: A*算法
- 回顾: 优先队列BFS、最短路
- A*算法 – 估价函数
- 为什么?
- A*算法
- 实战
回顾: 优先队列BFS、最短路
普通BFS:按层扩展
优先队列BFS:每次从队列中取出当前代价最小的状态进行扩展
优先队列BFS的局限性:
一个状态的当前代价最小,只能说明从起始状态到该状态的代价很小,而在未来的搜索中,从该状态到目标状态可能会花费很大的代价。反之亦然。当前代价较大,也许未来代价较小,总代价反而更优。优先队列BFS缺少对未来的预估。
A*算法 – 估价函数
A*算法是一种启发式搜索(Heuristically Search)算法
A*算法的关键是设计一个估价函数:
- 以任意“状态”为输入,计算出从该状态到目标状态所需代价的估计值
- 在搜索中,维护一个堆(优先队列),优先选择“当前代价+未来估价”最小的状态进行扩展
估价函数的设计原则:估值必须比实际更优(估计代价≤未来实际代价)
只要保证上述原则,当目标状态第一次从堆中被取出时,就得到了最优解
为什么?
把好状态估差的后果:
本来在最优解搜索路径上的状态被错误地估计了较大的代价,被压在堆中无法取出,从而导致非最优解搜索路径上的状态不断扩展,直至在目标状态上产生错误的答案
把坏状态估好的后果:
只要估价不大于未来实际代价,这个值总会比最优解更早地被取出,从而得到修正。最坏后果无非就是算的状态多了,跑得慢一些。
否决一个正确idea vs 多看一个垃圾idea
A*算法
A*和优先队列BFS的区别就是:考虑优先级的时候有没有加上未来估价
估价越精准(接近但不超过未来实际代价),A*算法越快
估价等于0,就退化为了优先队列BFS
A*算法的关键:开动脑筋,设计优秀的估价函数(必须要乐观估计,但也要尽量精准)
例如:求第K短路,把当前结点到终点的最短路作为估价函数(最短≤K短)
优先选择“当前走过的路径长度+估价函数”最小的状态扩展
实战
773.滑动谜题
https://leetcode.cn/problems/sliding-puzzle/
class Solution {public:int slidingPuzzle(vector<vector<int>>& board) {string start = zip(board);string target = zip({{1, 2, 3}, {4, 5, 0}});//q.push(start);q.push({-evaluate(start), start});depth[start] = 0;while (!q.empty()) {string s = q.top().second;q.pop();int pos = findZeroIndex(s);if (pos >= 3) expand(s, pos, pos - 3);if (pos <= 2) expand(s, pos, pos + 3);if (pos % 3 != 0) expand(s, pos, pos - 1);if (pos % 3 != 2) expand(s, pos, pos + 1);if (depth.find(target) != depth.end()) return depth[target];}return -1;}private:int evaluate(string &s) {int now[6];for (int i = 0; i < 6; i++) {if (s[i] != '0')now[s[i] - '0'] = i;}int target[6] = {0 ,0 ,1, 2, 3, 4};int ans = 0;for (int digit = 1; digit <= 5; digit++) {int nowx = now[digit] / 3;int nowy = now[digit] % 3;int targetx = target[digit] / 3;int targety = target[digit] % 3;ans += abs(nowx - targetx) + abs(nowy - targety);}return ans;}void expand(string& s, int pos, int other) {string ns = s;swap(ns[pos] , ns[other]);if (depth.find(ns) != depth.end()) return;depth[ns] = depth[s] + 1;q.push({ - depth[ns] - evaluate(ns), ns});//q.push(ns);}string zip(const vector<vector<int>>& board) {string res;for (int i = 0; i < 2; i++) {for (int j = 0; j < 3; j++) {res += '0' + board[i][j];}}return res;}int findZeroIndex(string& s) {for (int i = 0; i < 6; i++) if (s[i] == '0') return i;return -1;}//queue<string> q;priority_queue<pair<int, string>> q;unordered_map<string, int> depth;
};
选做题
八数码
https://www.acwing.com/problem/content/847/
https://www.acwing.com/problem/content/181/
推荐一个零声学院免费公开课程,个人觉得老师讲得不错,分享给大家:Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等技术内容,立即学习
启发式搜索: A*算法相关推荐
- poj 2449 Remmarguts' Date 启发式搜索 A*算法
做这个题算是学了学spfa算法,一开始感觉spfa和dij好像:dij找最小点松弛,spfa就是一个一个的松弛,松到不能松. 求S到T的第K短路 思路:这个算法的思路是从源点S优雅的暴力跑bfs,用优 ...
- 搜索 —— 启发式搜索 —— A* 算法
[概述] A*(A-Star)算法是一种在静态路网中,求解最短路的最有效的直接搜索方法,也是解决许多搜索问题的有效算法之一. A* 算法实际上是对 Dijkstra 算法的优化后得到的,关于 Dijk ...
- 启发式搜索 A*算法的OC 实现
前两天重新学习了下A*算法,上次学习A*算法已经是5年前了,看到网上铺天盖地的A*算法都是C.C++等等其他语言的,就是没有OC 的,所以抽空写了一份.今天太晚了就不说明A*算法的细节了,大家如果想学 ...
- 启发式搜索A*算法【引入及思想】
算法介绍 A*(念做:A Star)算法是一种很常用的路径查找和图形遍历算法.它有较好的性能和准确度. A*算法最初发表于1968年,由Stanford研究院的Peter Hart, Nils Nil ...
- 路径规划之 A* 算法
算法介绍 A*(念做:A Star)算法是一种很常用的路径查找和图形遍历算法.它有较好的性能和准确度.本文在讲解算法的同时也会提供Python语言的代码实现,并会借助matplotlib库动态的展示算 ...
- 15数码 java_A*算法求解15数码问题
目录 一.问题描述 二.算法简介 三.算法步骤 四.评估函数 五.参考资料 六.源代码(Java实现) 一.问题描述 利用A*算法进行表1到表2的转换,要求空白块移动次数最少. 转换规则为:空白块只可 ...
- 寻路之 A* 搜寻算法
最近做到一道题,题目如下: 有 A.B 两点,中间有一堆障碍物,求出A点到B的可行的路径,写出一个 DEMO 并可用任何语言实现(要求可以任意设置 A.B 点和障碍物的位置,需要做UI). 首先,理解 ...
- A-star 算法原理分析
搜索算法 图论中,应用最广泛的就是搜索算法了,比如,深度优先搜索.广度优先搜索等.在介绍 Dijkstra 算法那篇中,除了深度优先.广度优先这种暴力搜索算法,还有一些最短路算法也可以求得最短路径,并 ...
- 路径规划—— A* 算法
参考原文:路径规划之 A* 算法 (weibo.com) A*(念做:A Star)算法是一种很常用的路径查找和图形遍历算法.它有较好的性能和准确度. 本... 路径规划之 A* 算法 A*(念做:A ...
最新文章
- 01背包【动态规划】
- 安卓开发日记(1) - 安装 Android 开发环境和 first app
- 信息系统项目管理师-第5章:项目范围管理-重点汇总
- Hadoop:eclipse配置hadoop-eclipse-plugin(版本hadoop2.7.3)
- python需要配置环境变量吗_教你手动设置python环境变量
- 截取字符串,但要保证汉字不被截取半个
- 提问的智慧 如何得到好的帮助(转)
- Android之MediaProjectionManager实现手机截屏总结
- php base64安全吗,php base64
- matlab色度椭圆,matlab画色度图
- 爬取哔哩哔哩单个视频
- 这可能是最简单,精炼,有效的magisk 安装教程,附boot.img 提取方法
- boost 进程间通信-share memery传递字符串
- shuipfcms二次开发之图片上传
- Cadence Allegro如何导出与导入规则
- 2022年5月编程语言排行榜:C# 获得最多排名积分
- 禾川Q0 PLC ModbusRTU通讯
- 第13节 IIS之WEB服务器部署及网站发布——以win2003为例
- py使用polar绘制霍兰德职业测试雷达图
- [转载备用]微信直播的优势及微信直播搭建过程(点赞:主播妹子有点靓哦)
热门文章
- mysql数据库误删且未持久化_MySQL恢复误删数据解决方案
- 【Argoverse 1 Motion Forecasting Dataset】轨迹预测数据集简介
- fedora 下常用软件安装
- Notification 加入本地的声音文件
- 【网络通信】WSAStartup()函数,MAKEWORD的使用
- C语言实现获取文件后缀、修改后缀
- (4) STM32 AS608指纹识别模块测试代码
- 7-7 六度空间 (30 point(s))
- win左下角搜索框打不开,没有响应解决办法
- 学会OpenStack之核心Nova服务一篇就够了!!!