导读:本期聚焦于小伙伴创作的《深入理解A算法:单优先队列实现与CLOSED集的作用是什么》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《深入理解A算法:单优先队列实现与CLOSED集的作用是什么》有用,将其分享出去将是对创作者最好的鼓励。

A算法是启发式搜索中应用非常广泛的路径规划算法,核心思路是通过评估函数f(n)=g(n)+h(n)来指导搜索方向,其中g(n)是从起点到当前节点的实际代价,h(n)是当前节点到终点的预估代价。合理的实现方式能让算法在保证找到最优路径的同时,尽可能减少不必要的搜索开销。

深入理解A算法:单优先队列实现与CLOSED集的作用是什么

单优先队列的实现逻辑

单优先队列在A算法中用来存储待扩展的节点,队列的排序规则是按照节点的f值从小到大排列,每次从队列头部取出f值最小的节点进行扩展,这样就能优先搜索更有可能通向终点的路径。

实现单优先队列时,我们可以使用堆结构来维护队列,堆的插入和取出最小值的操作时间复杂度都是O(logn),能很好地满足A算法的性能需求。下面是一个基于Python的优先队列实现示例:

import heapq

class PriorityQueue:
    def __init__(self):
        self.heap = []
        self.count = 0  # 用来处理f值相同时的排序问题

    def push(self, item, priority):
        heapq.heappush(self.heap, (priority, self.count, item))
        self.count += 1

    def pop(self):
        if not self.is_empty():
            return heapq.heappop(self.heap)[2]
        return None

    def is_empty(self):
        return len(self.heap) == 0

    def size(self):
        return len(self.heap)

CLOSED集的作用解析

CLOSED集是用来存储已经被扩展过的节点的集合,它的核心作用是避免算法重复扩展同一个节点,减少无效搜索,提升整体运行效率。

避免重复扩展

在A算法的搜索过程中,同一个节点可能会因为不同的父节点被多次加入优先队列。如果不设置CLOSED集,每次从队列取出节点时都需要重新扩展,会造成大量的重复计算。当节点被扩展后,就把它加入CLOSED集,后续再遇到这个节点时,直接跳过扩展即可。

保证路径最优性

对于保证h(n)满足可采纳性的A算法,当节点第一次被加入CLOSED集时,对应的g(n)已经是从起点到该节点的最小代价。后续即使有其他路径到达该节点,g(n)也不会更小,因此不需要再重新扩展该节点,这也保证了最终找到的路径是最优的。

完整的A算法实现示例

下面是一个结合单优先队列和CLOSED集的完整A算法实现,用来在二维网格中寻找从起点到终点的最短路径:

# 定义节点类
class Node:
    def __init__(self, x, y, g=0, h=0, parent=None):
        self.x = x
        self.y = y
        self.g = g  # 起点到当前节点的实际代价
        self.h = h  # 当前节点到终点的预估代价
        self.f = g + h  # 评估函数值
        self.parent = parent  # 父节点,用来回溯路径

    def __eq__(self, other):
        return self.x == other.x and self.y == other.y

    def __hash__(self):
        return hash((self.x, self.y))

# 曼哈顿距离作为启发函数
def manhattan_distance(node, end_node):
    return abs(node.x - end_node.x) + abs(node.y - end_node.y)

def a_star_search(grid, start, end):
    # 初始化优先队列和CLOSED集
    open_queue = PriorityQueue()
    closed_set = set()

    # 计算起点的h值
    start.h = manhattan_distance(start, end)
    start.f = start.g + start.h
    open_queue.push(start, start.f)

    # 定义四个移动方向:上、下、左、右
    directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]

    while not open_queue.is_empty():
        # 取出f值最小的节点
        current_node = open_queue.pop()

        # 如果到达终点,回溯路径
        if current_node == end:
            path = []
            while current_node:
                path.append((current_node.x, current_node.y))
                current_node = current_node.parent
            return path[::-1]

        # 将当前节点加入CLOSED集
        closed_set.add(current_node)

        # 扩展当前节点的相邻节点
        for dx, dy in directions:
            new_x = current_node.x + dx
            new_y = current_node.y + dy

            # 检查坐标是否在网格范围内
            if not (0 <= new_x < len(grid) and 0 <= new_y < len(grid[0])):
                continue
            # 检查是否是障碍物
            if grid[new_x][new_y] == 1:
                continue

            new_node = Node(new_x, new_y)
            # 计算新的g值
            new_g = current_node.g + 1
            # 如果新节点已经在CLOSED集里,跳过
            if new_node in closed_set:
                continue

            # 计算新节点的h和f值
            new_node.h = manhattan_distance(new_node, end)
            new_node.f = new_g + new_node.h

            # 检查新节点是否在优先队列中,这里简化为直接加入,实际实现可以更严谨
            # 因为优先队列会按照f值排序,即使重复加入,先取出的也是f值更小的
            new_node.g = new_g
            new_node.parent = current_node
            open_queue.push(new_node, new_node.f)

    # 没有找到路径
    return None

# 测试示例
if __name__ == "__main__":
    # 0表示可通行,1表示障碍物
    grid = [
        [0, 0, 0, 0],
        [0, 1, 1, 0],
        [0, 1, 0, 0],
        [0, 0, 0, 0]
    ]
    start_node = Node(0, 0)
    end_node = Node(3, 3)
    path = a_star_search(grid, start_node, end_node)
    if path:
        print("找到的路径是:", path)
    else:
        print("没有找到可行路径")

实现注意事项

在实际实现时,需要注意几个细节:一是优先队列中如果有多个节点f值相同,需要保证排序的稳定性,上面的实现中加入了count变量来解决这个问题;二是CLOSED集的存储可以使用哈希表,这样判断节点是否存在的时间复杂度是O(1),效率更高;三是启发函数h(n)需要满足可采纳性,也就是不能高估从当前节点到终点的实际代价,否则算法可能无法找到最优路径。

通过单优先队列管理待扩展节点,配合CLOSED集避免重复搜索,A算法就能高效地完成路径规划任务,这两个组件是A算法实现中非常重要的部分,理解它们的作用能帮助我们更好地应用和优化A算法。

A_algorithm优先队列CLOSED集路径规划修改时间:2026-06-23 01:27:39

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。