A-star 寻路算法的伪代码表示

本文提供了A-star 算法的伪代码,可以对正在编码实现A-star的读者提供帮助。参照本文提供的伪代码可以快速编程实现A-star。

1、伪代码中的符号说明:
current节点:每次迭代时,Open_list中F值最小的那个节点
G:G值,从“当前节点” current 移动到起点start的代价
H:H值,预计从“当前节点”current移动到终点end的预估代价(估算成本)
F:F值,从起点start到终点end路过current节点的路径的估算总代价
F = G + H
neighbor节点:current节点的所有合法的neighbor节点(即:忽略掉那些不可到达的节点、已被放入Close_list中的节点,以及其它非法情形下的节点)

G值用于标识“与’当前节点’(current)相邻的”那些节点(neighbor)中,哪一个节点到起点start的代价最小。G值最小的那个neighbor即为到起点start的代价最小的那个节点。
F值用于确定下一个将要处理的“当前节点”current,F值最小的节点即为下一个将要处理的“当前节点”

2、算法基本过程
(1)将Open_list中F值最小的“当前节点”current自身移入Close_list, 将“与current节点相邻的所有合法节点neighbor”移入Open_list.即:
Open_list.erase(current)
Close_list.insert(current)

(2)Open_list中的所有节点将被遍历,从中找出F值最小的那个节点,作为下一次迭代时的current节点。因此,上一步中将”current自身移入Close_list”是为了避免其反复被迭代而无法迭代到其它的节点。

*CASE 1: 在每次的迭代中,如果某个(某些)neighbor是新加入Open_list的,则该neighbor的父节点就是current节点,该neighbor的G值等于其父节点(即current节点)的G值加上该neighbor到其父节点的代价P。公式如下:

neighbor.Father = current
neighbor.G = G(current) + P(current_to_neighbor)
neighbor.H = neighbor到终点end的预估代价
neighbor.F = neighbor.G + neighbor.H
Open_list.insert(neighbor)

*CASE 2: 如果某个(某些)neighbor早已存在于open表,则G(neighbor)必定已存在,它衡量了从该neighbor到起点start的代价。那么,到底是该代价G(neighbor)更小?还是neighbor经过current节点到达起点start的代价G’(neighbor)更小?此时需要先计算G’(neighbor)。计算的方法与上面计算G值的方法相同,即:
G’(neighbor) = current.G + P(current_to_neighbor)

若G(neighbor)小于G’(neighbor),说明该neighbor无需经过当前current节点即可以更小的代价到达起点start,此时什么都不需要做。若G(neighbor)大于G’(neighbor),说明要想从该neighbor节点以更小的代价到达起点start,则必须经过当前节点current,此时则需要将该neighbor的父节点改成current节点,其G值也应该改成G’(neighbor)的值。

3、A-star 伪代码:

start.Father = null
start.G = 0
start.H = start 到end的预估代价
start.F = start.G + start.H
Open_list.insert( start )

While( !Open_list.empty() || Open_list.find(end) == Open_list.end())   //迭代访问Open_list中的所有元素,直到Open_list为空,或者end节点存在于Open_list中时,才停止迭代
{
    auto current = Open_list.get_Element_With_Minimum_F_Value()  //每次迭代开始时都选择F值最小的那个节点作为current节点
    Auto allNeighbors[ ] = getAllNeighborNodes( current )  //获取current节点的所有合法的neighbor节点(即忽略掉那些不可到达的节点、已被放入Close_list中的节点,以及其它非法情形下的节点)
    Open_list.erase(current)   //将current节点从Open_list移到Close_list,避免while循环变成死循环
    Close_list.insert(current)

    For( auto neighbor in allNeighbors[ ] )   //遍历current节点的所有neighbor节点,确保neighbor节点的G值尽可能小(即neighbor节点到start节点的代价尽可能小)
    {
        auto neighbor_G_whith_current = current.G + P(current_to_neighbor)
        If( open_list.find(neighbor) == open_list.end() )    //如果当前neighbor节点不在open_list则将其放入open_list
        {
            neighbor.Father = current
            neighbor.G = neighbor_G_whith_current
            neighbor.H = neighbor到终点end的预估代价
            neighbor.F = neighbor.G + neighbor.H
            Open_list.insert(neighbor)
        }
        Else       //如果当前neighbor节点已存在于open_list,并且它通过current节点到达start节点的G值小于其本身原有的G值,则将这个neighbor节点的Father节点改成current节点,并刷新G值、H值、F值。否则什么都不做。
        {
            If( neighbor_G_whith_current < neighbor.G)
            {
                neighbor.Father = current
                neighbor.G = neighbor_G_whith_current
                neighbor.H = neighbor到终点end的预估代价
                neighbor.F = neighbor.G + neighbor.H
            }
        }
    }
}

Auto it = Open_list.find(end)
If( it != Open_list.end())
{
    //求路成功,输出结果
    Cout << “Route from end to start:” << endl
    For(Auto pNodePointer = &(*it); null != pNodePointer->parent; pNodePointer = pNodePointer->parent)
    {
        Cout << pNodePointer->parent->nodeID << endl
    }
}
Else
{
    //求路失败,从start节点到end节点不存在路径
    Cout << “No route from start to end!!!” << endl;
    Return false;
}

Return true
A*(A-star算法是一种启发式搜索算法,常用于解决寻路问题,特别是在游戏开发、机器人导航等场景中非常实用。它的核心思想是利用对目标节点的估计距离和实际路径长度来指导搜索过程,从而尽可能找到最短路径。 下面是C++实现A*算法的一个简单示例: ```cpp #include <iostream> #include <vector> #include <queue> // 定义图中的节点结构 struct Node { int x, y; int cost; // 到起点的成本 int heuristic; // 从当前节点到目标点的启发式估算值 bool visited; // 是否访问过 Node(int _x, int _y) : x(_x), y(_y), cost(0), heuristic(heuristic_cost(x, y)), visited(false) {} }; int heuristic_cost(int x, int y) { // 用曼哈顿距离作为启发式函数 return abs(x - target_x) + abs(y - target_y); } bool operator<(const Node& a, const Node& b) { return a.cost + a.heuristic > b.cost + b.heuristic; } void a_star_search(Node** grid, int width, int height, int startX, int startY, int endX, int endY) { std::priority_queue<Node, std::vector<Node>, std::greater<Node>> open_list; open_list.push({startX, startY, 0, heuristic_cost(startX, startY)}); Node* start = new Node(startX, startY); while (!open_list.empty()) { Node current = open_list.top(); open_list.pop(); if (current.x == endX && current.y == endY) { print_path(current); break; } current.visited = true; for (int dx = -1; dx <= 1; dx++) { for (int dy = -1; dy <= 1; dy++) { int newX = current.x + dx; int newY = current.y + dy; if (newX >= 0 && newX < width && newY >= 0 && newY < height && !grid[newX][newY].visited) { int newCost = current.cost + 1; // 每次移动花费1步 if (grid[newX][newY].cost > newCost) { grid[newX][newY].cost = newCost; grid[newX][newY].parent = &current; grid[newX][newY].heuristic = heuristic_cost(newX, newY); open_list.push(grid[newX][newY]); } } } } } } // 打印路径 void print_path(Node* node) { std::cout << "Path found from (" << node->x << ", " << node->y << ") to (" << endX << ", " << endY << ")\n"; Node* parent = node->parent; while (parent != nullptr) { std::cout << "(" << parent->x << ", " << parent->y << ") "; parent = parent->parent; } std::cout << "\n"; } int main() { // 初始化网格和其他参数 // ... a_star_search(grid, width, height, startX, startY, endX, endY); return 0; } ``` 在这个示例中,`a_star_search`函数接受一个二维网格表示地图,以及起点和终点坐标。它使用优先队列存储待处理的节点,并按照F值(总成本+启发式成本)进行排序。当找到目标节点时,会调用`print_path`打印路径。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值