当前位置: 首页 > article >正文

人工智能A*-启发式函数、增量式 A* 算法

下面我们将结合更高效的启发式函数(如欧几里得距离)和增量式 A* 算法(D* Lite 算法的简化变体)来提高路径规划的效率。D* Lite 算法是一种适用于动态环境的路径规划算法,它能够在地图发生局部变化时,通过更新已有的路径信息来快速重新规划路径,而不需要重新进行全局搜索。

代码实现

import heapq
import math

# 地图类,用于管理地图信息和更新
class Map:
    def __init__(self, grid):
        self.grid = grid
        self.rows = len(grid)
        self.cols = len(grid[0])

    def get_neighbors(self, node):
        x, y = node
        neighbors = []
        for dx, dy in [(0, 1), (0, -1), (1, 0), (-1, 0)]:
            new_x, new_y = x + dx, y + dy
            if 0 <= new_x < self.rows and 0 <= new_y < self.cols and self.grid[new_x][new_y] == 0:
                neighbors.append((new_x, new_y))
        return neighbors

    def update_cell(self, x, y, new_value):
        self.grid[x][y] = new_value

# 节点类,用于存储节点信息
class Node:
    def __init__(self, x, y):
        self.x = x
        self.y = y
        self.g = float('inf')
        self.rhs = float('inf')
        self.key = [float('inf'), float('inf')]

    def __lt__(self, other):
        return self.key < other.key

# 欧几里得距离启发式函数
def heuristic(a, b):
    return math.sqrt((a[0] - b[0]) ** 2 + (a[1] - b[1]) ** 2)

# 计算节点的键值
def calculate_key(node, s_start, k_m):
    node.key = [min(node.g, node.rhs) + heuristic((node.x, node.y), s_start) + k_m,
                min(node.g, node.rhs)]
    return node

# 初始化 D* Lite 算法
def initialize(s_start, s_goal):
    U = []
    nodes = {}
    for i in range(map_obj.rows):
        for j in range(map_obj.cols):
            node = Node(i, j)
            nodes[(i, j)] = node
    s_goal_node = nodes[s_goal]
    s_goal_node.rhs = 0
    s_goal_node = calculate_key(s_goal_node, s_start, 0)
    heapq.heappush(U, s_goal_node)
    return U, nodes

# 更新节点的 rhs 值
def update_vertex(U, node, s_start, k_m):
    if node.g != node.rhs:
        node = calculate_key(node, s_start, k_m)
        for i, n in enumerate(U):
            if n.x == node.x and n.y == node.y:
                U[i] = node
                heapq.heapify(U)
                break
        else:
            heapq.heappush(U, node)
    else:
        for i, n in enumerate(U):
            if n.x == node.x and n.y == node.y:
                U.pop(i)
                heapq.heapify(U)
                break

# 计算最短路径
def compute_shortest_path(U, s_start, nodes, k_m):
    while U and (U[0].key < calculate_key(nodes[s_start], s_start, k_m) or
                 nodes[s_start].rhs > nodes[s_start].g):
        u = heapq.heappop(U)
        if u.g > u.rhs:
            u.g = u.rhs
        else:
            u.g = float('inf')
            update_vertex(U, u, s_start, k_m)
        for neighbor in map_obj.get_neighbors((u.x, u.y)):
            neighbor_node = nodes[neighbor]
            if neighbor != s_start:
                neighbor_node.rhs = min(neighbor_node.rhs,
                                        u.g + 1)
            update_vertex(U, neighbor_node, s_start, k_m)

# 路径规划函数
def d_star_lite(s_start, s_goal):
    U, nodes = initialize(s_start, s_goal)
    k_m = 0
    compute_shortest_path(U, s_start, nodes, k_m)
    path = []
    current = s_start
    while current != s_goal:
        path.append(current)
        neighbors = map_obj.get_neighbors(current)
        min_rhs = float('inf')
        next_node = None
        for neighbor in neighbors:
            neighbor_node = nodes[neighbor]
            if neighbor_node.rhs < min_rhs:
                min_rhs = neighbor_node.rhs
                next_node = neighbor
        if next_node is None:
            print("未找到可行路径!")
            return []
        current = next_node
    path.append(s_goal)
    return path

# 示例地图
map_grid = [
    [0, 0, 0, 0, 0],
    [0, 1, 1, 0, 0],
    [0, 0, 0, 0, 0],
    [0, 0, 1, 1, 0],
    [0, 0, 0, 0, 0]
]
map_obj = Map(map_grid)

# 起点和终点
s_start = (0, 0)
s_goal = (4, 4)

# 进行路径规划
path = d_star_lite(s_start, s_goal)
if path:
    print("规划的路径:", path)

# 模拟地图变化
map_obj.update_cell(2, 2, 1)
# 重新规划路径
path = d_star_lite(s_start, s_goal)
if path:
    print("地图变化后重新规划的路径:", path)

代码解释

  1. 地图类(Map

    • 用于管理地图信息,包括获取节点的邻居节点和更新地图单元格的值。
    • get_neighbors 方法返回节点的可通行邻居节点。
    • update_cell 方法用于更新地图中指定单元格的值。
  2. 节点类(Node

    • 存储节点的坐标、g 值(从起点到该节点的实际代价)、rhs 值(到该节点的最短路径的估计代价)和键值 key
  3. 启发式函数(heuristic

    • 使用欧几里得距离作为启发式函数,比曼哈顿距离更准确地估计节点到目标节点的代价。
  4. D Lite 算法相关函数*:

    • initialize:初始化 D* Lite 算法,创建节点字典和优先队列 U,并将目标节点加入队列。
    • calculate_key:计算节点的键值,用于优先队列的排序。
    • update_vertex:更新节点的 rhs 值,并根据情况更新优先队列。
    • compute_shortest_path:计算最短路径,不断更新节点的 grhs 值,直到找到最短路径或队列为空。
    • d_star_lite:主路径规划函数,调用上述函数完成路径规划。
  5. 主程序

    • 定义示例地图、起点和终点。
    • 调用 d_star_lite 函数进行路径规划,并输出规划结果。
    • 模拟地图变化,更新地图单元格的值,再次调用 d_star_lite 函数重新规划路径。

注意事项

  • 此代码是 D* Lite 算法的简化实现,实际应用中可能需要根据具体情况进行调整和优化。
  • 地图的表示和节点的代价计算可以根据实际需求进行修改,例如考虑不同地形的移动代价。
  • 欧几里得距离启发式函数在某些情况下可能不是最优的,需要根据具体场景选择合适的启发式函数。

http://www.kler.cn/a/537646.html

相关文章:

  • Vue 3 30天精进之旅:Day 17 - 样式和动画
  • kafka专栏解读
  • LIMO:少即是多的推理
  • C++设计模式
  • Pygame介绍与游戏开发
  • Golang的引用类型和指针
  • 余数相同问题(信息学奥赛一本通-1080)
  • 从基础到进阶,掌握 CSS 变量与calc()函数的完整指南
  • Deepseek部署的模型参数要求
  • 内核日志查看:dmesg命令
  • CSS 布局全面解析:从传统浮动到现代 Flexbox 和 Grid
  • harmonyOS生命周期详述
  • android skia渲染介绍
  • Arduino 型号的对比
  • 微信小程序如何使用decimal计算金额
  • STM32G474--Whetstone程序移植(单精度)笔记
  • TypeScript 中的对象类型:深入理解接口和类型别名
  • SpringBoot速成(六)自定义starter
  • 企业4个内外网数据摆渡问题需要注意
  • Kafka系列之:定位topic只能保存最新数据的原因
  • 全国计算机等级考试(NCRE)四级计算机网络考试大纲(2025年版)
  • Vite 为什么快,是怎么打包的
  • C# OpenCV机器视觉:智能水果采摘
  • 卷积神经网络(CNN)池化层的最大池化(Max Pooling)和 平均池化(Average Pooling)
  • Spring MVC异常处理:DefaultHandlerExceptionResolver的使用与实例
  • JDK实现动态代理介绍+案例