700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 启发式搜索: A*算法

启发式搜索: A*算法

时间:2018-11-20 20:37:03

相关推荐

启发式搜索: A*算法

启发式搜索: A*算法

回顾: 优先队列BFS、最短路A*算法 – 估价函数为什么? A*算法实战

回顾: 优先队列BFS、最短路

普通BFS:按层扩展

优先队列BFS:每次从队列中取出当前代价最小的状态进行扩展

优先队列BFS的局限性:

一个状态的当前代价最小,只能说明从起始状态到该状态的代价很小,而在未来的搜索中,从该状态到目标状态可能会花费很大的代价。反之亦然。当前代价较大,也许未来代价较小,总代价反而更优。优先队列BFS缺少对未来的预估。

A*算法 – 估价函数

A*算法是一种启发式搜索(Heuristically Search)算法

A*算法的关键是设计一个估价函数:

以任意“状态”为输入,计算出从该状态到目标状态所需代价的估计值在搜索中,维护一个堆(优先队列),优先选择“当前代价+未来估价”最小的状态进行扩展

估价函数的设计原则:估值必须比实际更优(估计代价≤未来实际代价)

只要保证上述原则,当目标状态第一次从堆中被取出时,就得到了最优解

为什么?

把好状态估差的后果:

本来在最优解搜索路径上的状态被错误地估计了较大的代价,被压在堆中无法取出,从而导致非最优解搜索路径上的状态不断扩展,直至在目标状态上产生错误的答案

把坏状态估好的后果:

只要估价不大于未来实际代价,这个值总会比最优解更早地被取出,从而得到修正。最坏后果无非就是算的状态多了,跑得慢一些。

否决一个正确ideavs多看一个垃圾idea

A*算法

A*和优先队列BFS的区别就是:考虑优先级的时候有没有加上未来估价

估价越精准(接近但不超过未来实际代价),A*算法越快

估价等于0,就退化为了优先队列BFS

A*算法的关键:开动脑筋,设计优秀的估价函数(必须要乐观估计,但也要尽量精准)

例如:求第K短路,把当前结点到终点的最短路作为估价函数(最短≤K短)

优先选择“当前走过的路径长度+估价函数”最小的状态扩展

实战

773.滑动谜题

/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;};

选做题

八数码

/problem/content/847/

/problem/content/181/

推荐一个零声学院免费公开课程,个人觉得老师讲得不错,分享给大家:Linux,Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒体,CDN,P2P,K8S,Docker,TCP/IP,协程,DPDK等技术内容,立即学习

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。