跳转至

A* search & Heuristics

Week 2 A* Search & Heuristic

1.4 Informed Search | Introduction to Artificial Intelligence

1.5 Local Search | Introduction to Artificial Intelligence

  • Heuristic:似乎翻译成"启发式的".

    Heuristic function: 启发式函数\(h(n)\),用于给出当前到达目标的预测成本.

    回忆一下UCS,这是一种基于当前累计成本的搜索方法。优先选择使累积成本函数\(g(n)\)最小的路径;而Greedy Search是基于Heuristic function给出的搜索方法,优先选择使启发函数\(h\)下降最快的路径.

    这里引入的A* Search的定性是a combination of greedy search and UCS,定义了综合函数\(f(n) = g(n)+h(n)\),每次优先选择其中\(f(n)\)最小的那条路径进行搜索.

  • A* isn't optimal,即非最优化的失效情形:如果heuristic远高于实际所需最低成本,那么不可能成功.

    相对地,if A is optimal, then \(h(n)\) is admissible, fulfilling the rule that: $\(0 \leq h(n) \leq h^*(n)\)\(,其中\)h^(n)$是当前位置离目标实际上的最短路线距离.

找到合适的heuristics是A*算法应用的核心.

  • 最优性定理及证明:A* Search is optimal when \(h(n)\) is admissible.

    首先假设有两个目标\(A, B\),其中\(A\)是主要的目标,\(B\)是次要目标,即\(f(A)<f(B) \Longrightarrow g(A) < g(B)\).

    现在假设fringe上有一个元素\(n\),则由$\(\begin{cases} f(A) = g(A) + h(A) = g(A) \\ f(n) = g(n) + h(n) \leq g(n)+h^*(n) = f(A)\end{cases} \Longrightarrow f(n) \leq f(A) < f(B)\)$

    于是可以知道\(A\)一定在\(B\)之前被遍历到,所以是optimal的.

  • A*搜索的伪代码:

    function A*-GRAPH-SEARCH(problem, frontier)
        reached ← an empty dict mapping nodes to the cost to each one
        frontier ← INSERT((MAKE-NODE(INITIAL-STATE[problem]),0), frontier)
        while not IS-EMPTY(frontier):
            node, node.CostToNode ← POP(frontier)
            if problem.IS-GOAL(node.STATE): return node
            if node.STATE not in reached or reached[node.STATE]  node.CostToNode:
                reached[node.STATE] = node.CostToNode
                for child-node in EXPAND(problem, node):
                    frontier ← INSERT((child-node, child-node.COST + CostToNode), frontier)
        return False
    
  • Dominance定义: If heuristic \(a\) is dominant over heuristic \(b\), then the estimated goal distance for a is greater than the estimated goal distance for b for every node in the state space graph. Mathematically,

    \[\forall n, h_a(n) \geq h_b(n)\]

    这里\(a\)\(b\)形成了dominant的关系,因为\(a\)是接近\(h^*\)的一种刻画.

    平凡启发式函数:The trivial heuristic is defined as \(h(n)=0\), and using it reduces A* search to UCS.

    半格结构:

    exact (精确启发式)
            |
        max(h_a, h_b) (最大值组合)
            /     \
        h_a      h_b (具体的启发式函数)
        |        /
        h_c      /    
        \      /
            zero (平凡启发式)
    

    这里给我们指出了一个方法,对于某一问题的多个方案所构建的\(h_1,h_2,\cdots,h_n\),取其中的max,仍然是heuristic的,我们可以通过这样的方法去逐步趋近exact。

  • A* Search的失效和consistent heuristic的引入:

    现在的约束条件仍然存在不足,比如下面的情形中,A* Search就失效了。所以我们还需要引入新的概念consistent heuristic function:

    如果对某个graph,其中所有的节点\(n\)都满足:$\(h(n) \leq c(n,n_{child})+h(n_{child})\)$,则称这是一个consistent heuristic function.

    证明:略. easy

让Claude 4.0 Sonnet来总结一下这四种搜索:

Tips

  • DFS(深度优先搜索)

    DFS采用"一条路走到黑"的策略。从起始节点开始,沿着一个分支尽可能深入,直到无法继续为止,然后回溯到上一个节点,探索其他分支。

    实现方式:通常使用栈(或递归调用栈)来记录路径

    时间复杂度\(O(V+E)\),其中\(V\)是顶点数,\(E\)是边数

    特点:内存占用相对较少,但不保证找到最短路径

  • BFS(广度优先搜索)

    BFS采用"逐层扩展"的策略。从起始节点开始,先访问所有相邻的节点,然后再访问这些节点的相邻节点,形成一圈一圈向外扩展的模式。

    实现方式:使用队列来存储待访问的节点

    时间复杂度\(O(V+E)\)

    特点:在无权图中能保证找到最短路径,但内存占用较大

  • Greedy(贪心算法)

    贪心算法在每一步都选择当前看起来最好的选项,基于某种启发式函数做出局部最优决策。在路径搜索中,通常选择距离目标最近的节点作为下一步。

    实现方式:通常使用优先队列,按照启发式函数值排序

    时间复杂度:取决于具体实现,一般为\(O(V \log V)\)

    特点:速度快,但不保证找到最优解

  • A*算法

    A*结合了Dijkstra算法的准确性和贪心算法的效率。它使用评估函数\(f(n) = g(n) + h(n)\),其中\(g(n)\)是从起点到当前节点的实际代价,\(h(n)\)是从当前节点到目标的启发式估计代价。

    实现方式:使用优先队列,按\(f(n)\)值排序,维护开放列表和关闭列表

    时间复杂度:取决于启发式函数的质量,最坏情况为\(O(b^d)\)

    特点:当启发式函数满足可接受性条件时,能保证找到最优解

  • 应用场景对比

    • DFS:适合深层搜索、拓扑排序、强连通分量查找
    • BFS:适合最短路径问题、层序遍历
    • Greedy:适合对速度要求高、对最优性要求不严格的场景
    • A*:适合游戏AI、路径规划等需要在效率和最优性之间平衡的应用

这四种算法各有优势,选择哪种取决于具体的问题需求和约束条件。