A*搜索算法

A*搜索算法

A*算法(A Star Search Algorithm),是一种搜索优化方法,结合了启发式搜索的方法以及dijkstra最短路算法的优先选取思路。

启发式搜索

何为启发式搜索?

启发式这个概念非常抽象且广泛。我个人理解的话,启发式其实方法有很多,算是诱导、启发程序往更好地方向进行运行的优化的一种总称。

在搜索过程中,设定一个启发式的估价函数g,和当前搜索消费cost。

如果cost+g已经比较大了,比如说大于限定值,那么我们就不必再搜索了,进行剪枝优化。

A*算法

采用优先队列,每次取出cost+g最小的,更新它的相邻节点,更新优先队列,直到找到目标解。

在dijkstra中,我们也是用优先队列来取当前距离最小的点,去更新其他点,这个过程是相似的。

直接上例题吧

例、八数码

完成八数码游戏。(任意局面->123804765)

我们采用当前局面与目标局面有多少个数不同作为估价函数g。

#include <bits/stdc++.h>
using namespace std;
const string st = "123804765";
string s;
map<string, int> m;
struct node
{
    string s;
    int dep, g;
    bool operator < (const node &x) const
    {
        return dep + g > x.dep + x.g;
    }
};
priority_queue<node> q;
int d(string x)
{
    int ans = 0;
    for (int i = 0; i < 9; ++i)
        if (st[i] != x[i])
            ++ans;
    return ans;
}
int main()
{
    cin >> s;
    q.push({s, 0, d(s)});
    m[s] = 1;
    while (1)
    {
        node t = q.top();
        q.pop();
        int pos;
        if (t.s == st)
        {
            cout << t.dep;
            break;
        }
        for (int i = 0; i < 9; ++i)
            if (t.s[i] == '0')
            {
                pos = i;
                break;
            }
        if (pos >= 3)
        {
            swap(t.s[pos], t.s[pos - 3]);
            if (!m[t.s] || m[t.s] > t.dep + 1)
                q.push({t.s, t.dep + 1, d(t.s)}),
                m[t.s] = t.dep + 1;
            swap(t.s[pos], t.s[pos - 3]);
        }
        if (pos < 6)
        {
            swap(t.s[pos], t.s[pos + 3]);
            if (!m[t.s] || m[t.s] > t.dep + 1)
                q.push({t.s, t.dep + 1, d(t.s)}),
                m[t.s] = t.dep + 1;
            swap(t.s[pos], t.s[pos + 3]);
        }
        if (pos % 3 != 0)
        {
            swap(t.s[pos], t.s[pos - 1]);
            if (!m[t.s] || m[t.s] > t.dep + 1)
                q.push({t.s, t.dep + 1, d(t.s)}),
                m[t.s] = t.dep + 1;
            swap(t.s[pos], t.s[pos - 1]);
        }
        if (pos % 3 != 2)
        {
            swap(t.s[pos], t.s[pos + 1]);
            if (!m[t.s] || m[t.s] > t.dep + 1)
                q.push({t.s, t.dep + 1, d(t.s)}),
                m[t.s] = t.dep + 1;
            swap(t.s[pos], t.s[pos + 1]);
        }
    }
    return 0;
}
posted @ 2022-02-22 15:44  cacu  阅读(211)  评论(0编辑  收藏  举报