2022年春季《人工智能》_EOJ B.路径导航

题目在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

思路

https://www.redblobgames.com/pathfinding/a-star/introduction.html

代码

先include一下有优先队列的头文件

double cost[maxn][maxn];
double A_star(int s, int t)
{
    int INF = 0x3f3f3f3f;
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            cost[i][j] = INF;
            if (edge[i][j])
            {
                cost[j][i] = cost[i][j] = distance(i, j);
            }
        }
    }
    // open表,小顶堆
    // <double,int>:f值,点编号(优先队列排序先以第一关键词排序,第一关键词相等再比较第二关键字)
    priority_queue<pair<double, int>, vector<pair<double, int>>, greater<pair<double, int>>> frontier;
    // 先放入起点,起点的f值为0
    pair<double, int> tmp(0, s);
    frontier.push(tmp);
    // close表
    // <int,double>:点编号,g值
    map<int, double> cost_so_far;
    // 起点的g值为0
    cost_so_far[s] = 0;
    // 起点没有父节点
    pos[s] = -1;
    // 当open表非空
    while (!frontier.empty())
    {
        // current为优先队列表头,即f值最小的结点
        int current = frontier.top().second;
        frontier.pop();
        if (current == t)
        {
            // 终点h=0
            return cost_so_far[current];
        }
        // 寻找相邻点,即待放入open表中的点
        for (int next = 0; next < n; next++)
        {
            // 有边,next为与current相邻的点
            if (cost[next][current] < INF)
            {
                // 求next的g
                double new_cost = cost_so_far[current] + cost[current][next];
                // next不在close中或新g比原来的路径更佳
                if (cost_so_far.count(next) == 0 || new_cost < cost_so_far[next])
                {
                    // 更新next的g值
                    cost_so_far[next] = new_cost;
                    // 求next的f值
                    // 注意此处使用distance作为h值,不是cost[next][t]
                    double priority = new_cost + distance(next, t);
                    // next进入open表
                    pair<double, int> tmp(priority, next);
                    frontier.push(tmp);
                    // 更新next的父节点
                    pos[next] = current;
                }
            }
        }
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值