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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值