首页 > 编程语言 >【搜索】【模板】A* 算法

【搜索】【模板】A* 算法

时间:2024-07-22 09:19:59浏览次数:8  
标签:cnt const int des bfs ++ 算法 搜索 模板

学了 IDA*,
然后学学 A*。

A*

A* 可以简单理解为在 bfs 的时候分个先后,哪个最有可能先到达就先走哪一步。

A* 是在某个最短路问题中(比如求最小的步骤等),如果所有边权都是非负的,那么就可以使用启发函数来优化 bfs 过程。

例题 P1379 八数码难题

思路

我们在 bfs 的过程中加入函数 \(h()\) 表示在某个状态下用最乐观的走法从当前状态到终止状态的步骤。

当然,不难想到 \(h()\) 函数比任何走法都要小。

估价函数 \(f(s)\) 就是在状态 \(s\) 下,已经走的距离 \(g(s)\) 加上最乐观的走法需要的步数 \(h(s)\),即 \(f(s) = g(s) + h(s)\)。

所以将 bfs 的 queue 改为 priority_queue,关键字为 \(f = g + h\),采用小根堆。

代码

#include <bits/stdc++.h>

#define node vector<vector<int> >

using namespace std;

const int N = 9;

map<node, int> s;
node g(3, vector<int>(3));
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};

node des = 
{
    {1, 2, 3},
    {8, 0, 4},
    {7, 6, 5}
};

int x[N], y[N];

struct cmpnode {
    node g;

    int h() const {
        int cnt = 0;
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                cnt += abs((i - x[g[i][j]])) + abs((j - y[g[i][j]]));
            }
        }
        return cnt;
    }

    bool operator>(const cmpnode b) const {
        return s[g] + h() > s[b.g] + b.h();
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    string tmp;
    cin >> tmp;
    for (int i = 0, cnt = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            g[i][j] = tmp[cnt++] - '0';
        }
    }

    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            x[des[i][j]] = i;
            y[des[i][j]] = j;
        }
    }

    priority_queue<cmpnode, vector<cmpnode>, greater<cmpnode> > q;
    q.push({g});
    s[g] = 0;

    while (q.size()) {
        g = q.top().g;
        auto t = g;
        q.pop();
        if (g == des) {
            cout << s[g] << '\n';
            return 0;
        }

        int sp_x = -1, sp_y = -1;
        for (int i = 0; i < 3; i++)
            for (int j = 0; j < 3; j++)
                if (g[i][j] == 0)
                    sp_x = i, sp_y = j;

        for (int i = 0; i < 4; i++) {
            int nx = sp_x + dx[i], ny = sp_y + dy[i];
            if (nx < 0 || ny < 0 || nx > 2 || ny > 2) continue;
            swap(g[sp_x][sp_y], g[nx][ny]);
            if (!s.count(g)) {
                s[g] = s[t] + 1;
                q.push({g});
            }
            swap(g[sp_x][sp_y], g[nx][ny]);
        }
    }
    return 0;
}

标签:cnt,const,int,des,bfs,++,算法,搜索,模板
From: https://www.cnblogs.com/Yuan-Jiawei/p/18315361

相关文章

  • 【数据结构】【模板】莫队
    莫队使用场景离线算法;区间询问不断修改。能用\(O(1)\)的时间复杂度从\([l,r]\)到\([l+1,r]\)或者\([l,r-1]\)。原理原问题可以转化为为建立一个坐标轴,对于一个询问\((l,r)\),相当于点\((l,r)\),从一个询问\((a,b)\)到\((c,d)\),可以理解为点\((a,b)......
  • 【图论】【模板】差分约束系统
    差分约束系统差分约束系统是将不等式组的问题转化为图论问题。前置知识判断负环例题P5960【模板】差分约束算法思路我们将\(x_u-x_v\ley_u\)换为\(x_u\lex_v+y_u\)。然后我们建立一条连接\(v,u\)(注意是\(v,u\)不是\(u,v\))权值为\(y_u\)的边。我们发......
  • 【图论】【模板】最长路、最短路
    最短路Dijkstra算法思路Dijkstra算法,采用贪心思想,在某一时刻如果\(dis\)数组中\(dis_u\)最小,那么就固定\(u\),\(dis_u\)一定是\(1\rightarrowu\)的最短路径,然后我们再通过\(u\)更新与\(u\)有边相连的\(v\),如果\(dis_v>dis_u+w\),那么\(dis_v=dis_u+w\)......
  • 【图论】【模板】判断负环
    使用SPFA算法判断负环前言判断负环是属于判定性的问题,常与二分结合起来。例题AcWing852.spfa判断负环思路可以使用SPFA进行判断。因为两点之间至多有\(n-1\)条边,所以当一个点的最短路径经过的边数大于等于\(n\)时,说明有负环。代码#include<bits/stdc++.h>......
  • 【搜索】【模板】模拟退火
    前置知识自然对数、分数次幂、概率。前言模拟退火可以在我们想不到题目正解的时候试一试其实就是骗分方法。因为纯随机得出正确答案的概率非常低,所以我们就可以加一定的优化,使找到答案概率增大。算法思想温度(步长):每次选择一个范围进行搜索,在搜索过程中范围不断缩小,最后到很......
  • 算法学习(算法笔记胡凡)
    目录考生排序递归问题数塔问题回文字符串棋盘覆盖问题盒分形自然数分解之最大积自然数分解之方案数01串STL练习迭代器的使用考生排序https://sunnywhy.com/sfbj/4/1/92结构体的使用,sort函数的使用递归问题数塔问题https://sunnywhy.com/sfbj/4/3/116动态规划问题dp例如给......
  • 洛谷算法题
    目录数字反转迪杰斯特拉算法背包问题字符串排序P1192台阶问题P1111修复公路炸铁路问题计数问题......
  • 按值搜索 JSON
    我正在尝试使用Python按其值而不是其变量来搜索json。基本上:我想在.ajson文件中搜索字符串/第二个值并返回第一个值我正在制作一个速记游戏,我试图这样做,以便我可以按单词搜索笔划。例如:“TKPWRAOEUPBD”:“grind”我搜索“grind”,它返回“TKPWRAOEUPBD......
  • 即使通过了示例测试用例,Dijkstra 算法也不起作用
    所以我遵循了维基百科关于Dijkstra算法和Brilliants的伪代码。https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm#Pseudocodehttps://brilliant.org/wiki/dijkstras-short-路径查找器/这是我的代码,它不起作用。谁能指出我的代码中的缺陷吗?#Usespyt......
  • 基于GA遗传算法的WSN网络节点覆盖优化matlab仿真
    1.程序功能描述      通过遗传优化算法,优化WSN无线传感器网络中的各个节点的坐标位置以及数量,使得整个网络系统已最少数量的节点达到最大的网络覆盖率。仿真最后输出覆盖率收敛曲线,节点数量收敛曲线,GA优化前后的覆盖率变化情况。 2.测试软件版本以及运行结果展示MATLA......