A*路径规划算法的Python实现

A*路径规划算法的Python实现

写在前面

今天因为要在Python上实现机器人建图导航的仿真,写了A*算法的Python实现,过来分享一下。
关于A*算法的原理网上有很多,这里就不再赘述了,直接贴代码。
open_list 和 close_list 都通过dict实现,因为dict底层是hash_map,代码整体效率还行。

Python代码

from copy import deepcopy
import numpy as np
import math

def path_plan_Astar(car_pos, target_pos, map):
    '''
    :param car_pos: [x,y] 出发点位置
    :param target_pos: [x,y]  终点位置
    :param map: map是二维list或二维ndarray,map[y][x]=value  value: 1:可行区域  其他:不可行区域
    :return: bool:是否成功规划  int:步数=len(path)   list:path经过的各个点[x,y]组成的列表,方向从 car_pos -> target_pos
    '''

    def is_point_in_map(map, point):  # 判断这个点是不是在map中
        height = len(map)
        width = len(map[0])
        x = point[0]
        y = point[1]
        if x >= 0 and x < width and y >= 0 and y < height:
            return True
        return False

    def Hn(car_pos, target_pos):  # 修改这个函数来实现各种H(n)
        # return abs(car_pos[0] - target_pos[0]) + abs(car_pos[1] - target_pos[1])
        x_err = car_pos[0] - target_pos[0]
        y_err = car_pos[1] - target_pos[1]
        return math.sqrt(x_err * x_err + y_err * y_err)

    map = np.array(deepcopy(map))
    car_pos = [int(car_pos[0]), int(car_pos[1])]
    target_pos = [int(target_pos[0]), int(target_pos[1])]

    open_list = {}
    close_list = {}
    open_list[str(car_pos)] = {"pos": car_pos, "Gn": 0, "parent_pos": None}
    path = []
    while True:
        # openlist为空,失败了
        if len(open_list) == 0:
            break
        # 如果openlist中有target_pos,则规划成功了
        if open_list.get(str(target_pos)) is not None:
            current_point_info = open_list[str(target_pos)]
            while True:
                path.append(current_point_info['pos'])
                if current_point_info['parent_pos'] is None:
                    path.append(current_point_info['pos'])
                    path.reverse()
                    return True, len(path), path  # 规划成功,返回路径
                current_point_info = close_list[str(current_point_info['parent_pos'])]

        # 找到open_list里Fn最小的点
        min_Fn = -1
        min_Fn_i = None
        for i in open_list:
            Fn = open_list[i]['Gn'] + Hn(open_list[i]['pos'], target_pos)
            if Fn < min_Fn or min_Fn < 0:
                min_Fn_i = i
                min_Fn = Fn

        # 将这个点转移到closed_list中
        point_info = deepcopy(open_list[min_Fn_i])
        open_list.pop(min_Fn_i)
        close_list[min_Fn_i] = point_info

        # 向外扩张 8邻域 并将可行点存入open_list中
        for x in range(point_info['pos'][0] - 1, point_info['pos'][0] + 1 + 1):
            for y in range(point_info['pos'][1] - 1, point_info['pos'][1] + 1 + 1):
                if x != point_info['pos'][0] or y != point_info['pos'][1]:
                    if is_point_in_map(map, [x, y]):
                        if map[y][x] == 1 and (open_list.get(str([x, y])) is None) and (
                                close_list.get(str([x, y])) is None):
                            new_point = {"pos": [x, y], "Gn": point_info["Gn"] + 1, "parent_pos": point_info['pos']}
                            open_list[str(new_point['pos'])] = new_point
    return False, 0, []  # 运行到这里一定是规划失败了,返回规划失败
### 回答1: A*(A-Star)是一种常用于路径规划问题的启发式搜索算法。它在可达目标的路径上根据估计的距离和代价来进行搜索,并在尽可能少的步骤内寻找最优解。下面是一个用300字来回答如何仿真A*路径规划算法的简要步骤: 1. 建立地图:首先,我们需要建立一个合适的地图来模拟路径规划问题。可以使用二维数组或栅格地图表示地图,其中不同的值代表该位置的障碍物或可通行程度。 2. 定义启发函数:A*算法的关键是定义一个启发函数,用于估计到目标点的剩余代价。常用的启发函数有欧几里得距离、曼哈顿距离等。 3. 初始化和数据结构:首先,需要初始化起始点和目标点,并创建一个开放列表和一个关闭列表。开放列表用于存储待探索的节点,关闭列表用于存储已经探索过的节点。 4. A*算法主循环:在每次循环中,从开放列表中选择估价最小的节点作为当前节点,并移至关闭列表。然后,对该节点的相邻节点(未访问或未在关闭列表)进行估价和代价计算,并加入开放列表。 5. 更新节点:如果相邻节点已经在开放列表中,并且通过当前节点的路径比之前更优,则更新该节点的代价和路径信息。 6. 终止条件:当目标节点进入关闭列表时,搜索结束。回溯路径时,按照每个节点的父节点找到从起点到终点的最优路径。 7. 可视化:最后,将生成的路径以及搜索过程可视化,方便观察算法的性能。 总结:通过按照上述步骤,我们可以仿真A*路径规划算法。需要注意的是,A*算法的效率和准确性受数据表示、启发函数和数据结构选择的影响。因此,我们应根据具体问题的需求进行适当调整和优化。 ### 回答2: A*(A-star)路径规划算法是一种常用的图搜索算法,用于找到从起点到终点的最短路径。仿真A*路径规划算法的步骤如下: 1. 定义地图:首先需要定义一个地图,可以使用二维数组或者图结构来表示。在地图中,根据实际情况标记出障碍物和起点终点位置。 2. 初始化数据结构:创建一个开放列表(Open List)和一个关闭列表(Closed List)。开放列表保存待处理的节点,关闭列表保存已经处理过的节点。 3. 将起点加入开放列表:将起点加入开放列表,并设置起点的代价值(F值)为0。 4. 开始搜索:进入循环,直到开放列表为空或者找到了终点。循环中,从开放列表中选择F值最小的节点作为当前节点。 5. 扩展当前节点:对当前节点的相邻节点进行扩展(可以选择上下左右相邻节点或者八个方向的相邻节点),计算扩展节点的代价值。更新扩展节点的父节点,并计算新的G值和H值。 6. 检查相邻节点:如果相邻节点已经在关闭列表中,忽略;如果相邻节点不在开放列表中,加入开放列表;如果相邻节点已经在开放列表中,更新相邻节点的父节点,并重新计算G值。 7. 判断终点:在每次扩展节点后,判断当前节点是否为终点。如果是终点,则搜索结束。 8. 搜索结束:如果开放列表为空,则搜索失败;如果找到了终点,则从终点开始回溯,可以得到最短路径。 通过以上步骤,我们可以仿真A*路径规划算法。在实际仿真中,可以使用计算机编程语言来实现算法,并在地图上显示搜索过程和最终路径,以便观察和分析算法的性能和准确性。 ### 回答3: A*(A-star)是一种常用的路径规划算法,用于计算两点间的最短路径。下面是一个用Python编写的简单的A*算法的仿真示例。 首先,需要创建一个地图,表示整个路径规划的环境。假设地图是一个二维网格,其中1代表障碍物,0代表可行路径。地图的大小可以根据实际情况进行设置。 接下来,定义A*算法中的基本数据结构。需要一个open_set列表来存储待探索的节点,以及一个closed_set列表来存储已经探索过的节点。还需要定义一个用于存储每个节点距离起始点的实际距离的字典(g_score)和一个用于存储每个节点距离目标点的估计距离的字典(h_score)。此外,还需要一个用于回溯路径的字典(parent)。 在算法开始之前,需要初始化open_set,将起始点加入其中,并将起始点的g_score和h_score都置为0。同时,将起始点的parent设为None。 接下来,开始循环,直到open_set为空。在每次循环中,选择open_set中具有最低f_score(即g_score和h_score之和)的节点作为当前节点,并将其移到closed_set。 然后,对当前节点的邻居节点进行探索。如果邻居节点已经在closed_set中,跳过该节点。否则,如果邻居节点不在open_set中,则将其加入open_set,并更新邻居节点的g_score、h_score和parent。 如果邻居节点已经在open_set中,比较新计算得到的g_score和原来的g_score的大小。如果新的g_score更小,则更新邻居节点的g_score和parent。 最后,当目标节点在open_set中时,说明已经找到了一条最短路径。可以通过回溯parent字典,从目标节点一直追溯到起始点,得到完整的路径。 总结:A*算法通过不断探索邻居节点,并根据节点的实际距离和估计距离来选择下一个节点,最终找到起始点到目标点之间的最短路径。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值