• A*寻路基本概念和C++实现A*算法


    前言

    要先了解A*算法,得首先了解BFS——广度优先遍历

    关于BFS

    广度优先搜索(BFS)基本概念
    算法基础:BFS和DFS的直观解释

    关于A*

    了解BFS之后,我们发现BFS不是很智能,BFS需要去遍历当前节点所有旁边的点,它是没有目标性的,像洪水一样,移动方向是四面八方。
    我们想要把它变得更智能一点,也就是有目的性的去找终点。
    这里就有一个启发函数

    F = G + H

    假设现在是从起点A终点B

    • G = 从起点A,沿着产生的路径,移动到网格上指定方格的移动耗费。
    • H = 从网格上那个方格移动到终点B的预估移动耗费。这经常被称为启发式的,可能会让你有点迷惑。这样叫的原因是因为它只是个猜测。我们没办法事先知道路径的长度,因为路上可能存在各种障碍(墙,水,等等)。虽然本文只提供了一种计算H的方法,但是你可以在网上找到很多其他的方法。(计算H的方法一般为:曼哈顿距离、欧几里得距离)

    有了这个启发函数,那么就会让我们的寻路算法更加智能,因为它有了一个目标,往这个最终目标移动就行了。

    具体可以看看这篇文章:A星(A*, A Star)算法详解.
    这个是视频A*寻路算法详解 #A星 #启发式搜索

    C++代码实现

    #include 
    #include 
    #include 
    using namespace std;
    
    typedef pair<int, int> pii;//(横坐标,纵坐标)
    typedef pair<int, pii> piii;//(当前点的F值,pii)
    
    int dx[4] = {0, 1, 0, -1}, dy[4] = {1, 0, -1, 0};//四个方向
    const int N = 1e3 + 10;
    int g[N][N];//地图
    map<pii, int> g_costs;//当前点到起点的G值
    map<pii, pii> parent;//记录当前节点的父节点,用于找到最终路径
    
    //H值,我这里计算的是曼哈顿距离
    int Get_H(int cur_x, int cur_y, int ed_x, int ed_y){
        return abs(ed_y - cur_y) + abs(ed_x - cur_x);
    }
    
    string Get_Path(pii st_point, pii ed_point){
        string path = "";
        pii cur_point = ed_point;
        while(cur_point != st_point){
            path += "(" + to_string(cur_point.first) + "," + to_string(cur_point.second) + ") <- ";
            cur_point = parent[cur_point];
        }
        path += "(" + to_string(cur_point.first) + "," + to_string(cur_point.second) + ")";
        return path;
    }
    
    int A_Star(int st_x, int st_y, int ed_x, int ed_y, int n, int m){
        priority_queue<piii, vector<piii>, greater<piii>> heap;
        heap.push({0, {st_x, st_y}});
        while(heap.size()){
            piii now = heap.top();
            heap.pop();
            pii point = now.second;
            if(point.first == ed_x && point.second == ed_y) return now.first;
            for(int i = 0; i < 4; i++){
                int nx = point.first + dx[i], ny = point.second + dy[i];
                int new_cost = g_costs[point] + 1;
                pii ne_point = {nx, ny};
                if(nx < 0 || nx >= n || ny < 0 || ny >= m || g[nx][ny] == 0) continue;
                if(parent.count(ne_point) == 0 || new_cost < g_costs[ne_point]){
                    g_costs[ne_point] = new_cost;
                    int f = new_cost + Get_H(nx, ny, ed_x, ed_y);
                    heap.push({f, ne_point});
                    parent[ne_point] = point;
                }
            }
        }
        return -1;
    }
    
    int main(){
        int n, m;
        int st_x, st_y, ed_x, ed_y;
        cin >> n >> m;
        for(int i = 0; i < n; i++){
            for(int j = 0; j < m; j++){
                cin >> g[i][j];
            }
        }
        cin >> st_x >> st_y >> ed_x >> ed_y;
        cout << "起点: (" << st_x << "," << st_y << ")\n";
        cout << "终点: (" << ed_x << "," << ed_y << ")\n";
        cout << "距离为" << A_Star(st_x, st_y, ed_x, ed_y, n, m) << "步" << '\n';
        cout << "具体路径为\n";
        cout << Get_Path({st_x, st_y}, {ed_x, ed_y});
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71

    在这里插入图片描述

  • 相关阅读:
    CarSim仿真高级进阶(三)---VS 命令行(3)
    【云原生之Docker实战】使用Docker部署siyuan个人笔记系统
    【华为OD机试真题 JS】贪吃蛇
    1.4_9 Axure RP 9 for mac 高保真原型图 - 案例8 【动态面板】浏览、翻页、回弹
    Nginx多IP端口路由配置
    【强化学习论文】离线元强化学习中基于对比学习的稳定表示
    vue无感刷新
    微服务11-Sentinel中的授权规则以及Sentinel服务规则持久化
    【Spring底层原理高级进阶】Spring Kafka:实时数据流处理,让业务风起云涌!️
    BUUCTF-ez_pz_hackover_2016
  • 原文地址:https://blog.csdn.net/qq_52855744/article/details/126268974