📜  A *搜索算法(1)

📅  最后修改于: 2023-12-03 14:59:10.148000             🧑  作者: Mango

A*搜索算法

A搜索算法是一种启发式搜索算法,可以用于在图形地图上寻找最短路径。它结合了广度优先搜索和贪心算法的优点,可以更快地找到最优解。在本文中,将介绍A搜索算法如何工作以及如何在代码中实现。

工作原理

A搜索算法使用估价函数来评估每个节点的代价。估价函数使用两个因素来计算代价:从起始节点到该节点的已知代价(称为g值)和从该节点到目标节点的估计代价(称为h值)。A算法将这些代价相加得到节点的总代价f值。选择总代价最小的节点进行扩展。在搜索过程中,A算法会维护一个开放列表和一个关闭列表。开放列表包含待访问的节点,而关闭列表包含已经访问过的节点。每当从开放列表中选取一个节点来扩展时,A算法将该节点移到关闭列表中,并从其邻居中选取最小的f值来进行扩展。如果下一个节点已经在开放列表中,则更新该节点的代价。

伪代码

以下是A*搜索算法的伪代码:

function A*(start,goal)
    closedset := the empty set                 // 已被访问的节点集合
    openset := {start}                         // 待访问的节点集合,初始化为起始节点
    came_from := the empty map                 // 储存路径

    g_score[start] := 0                         // 起始节点到起始节点的已知代价为0
    h_score[start] := heuristic_cost_estimate(start, goal) // 从起始节点到目标节点的估计代价
    f_score[start] := h_score[start]            // 起始节点到目标节点的总代价

    while openset is not empty
        current := the node in openset having the lowest f_score[] value
        if current = goal                        // 到达目标节点
            return reconstruct_path(came_from, goal)

        remove current from openset
        add current to closedset

        for each neighbor of current
            if neighbor in closedset
                continue        // 忽略已经被访问过的节点

            tentative_g_score := g_score[current] + dist_between(current, neighbor) // 通过当前节点到达邻居节点的已知代价
            if neighbor not in openset
                add neighbor to openset
                tentative_is_better := true        // 第一次访问到该节点,更新代价
            else if tentative_g_score < g_score[neighbor]
                tentative_is_better := true        // 最优路径应该被更新
            else
                tentative_is_better := false

            if tentative_is_better = true
                came_from[neighbor] := current
                g_score[neighbor] := tentative_g_score
                h_score[neighbor] := heuristic_cost_estimate(neighbor, goal)
                f_score[neighbor] := g_score[neighbor] + h_score[neighbor]

    return failure
示例代码

以下是使用Python编写的示例代码:

def A_star(start,goal,neighbors_fn,heuristic_fn): 
    closedset = set() # 已被访问的节点集合
    openset = {start} # 待访问的节点集合,初始化为起始节点
    came_from = {} # 储存路径

    g_score = {start:0} # 起始节点到起始节点的已知代价为0    
    h_score = {start:heuristic_fn(start,goal)} # 从起始节点到目标节点的估计代价    
    f_score = {start:g_score[start] + h_score[start]} # 起始节点到目标节点的总代价

    while openset:
        current = min(openset, key = lambda node: f_score[node]) # 找到当前待访问节点
        if current == goal: # 到达目标节点
            return reconstruct_path(came_from,goal)

        openset.remove(current)
        closedset.add(current)

        for neighbor in neighbors_fn(current):
            if neighbor in closedset:
                continue

            tentative_g_score = g_score[current] + dist_between(current,neighbor) # 通过当前节点到达邻居节点的已知代价
            if neighbor not in openset:
                openset.add(neighbor)
                tentative_is_better = True
            elif tentative_g_score < g_score[neighbor]:
                tentative_is_better = True
            else:
                tentative_is_better = False

            if tentative_is_better:
                came_from[neighbor] = current
                g_score[neighbor] = tentative_g_score
                h_score[neighbor] = heuristic_fn(neighbor,goal)
                f_score[neighbor] = g_score[neighbor] + h_score[neighbor]

    return None
总结

A搜索算法是一种快速的寻找最短路径的算法。它使用估价函数来评估每个节点的代价,从而更快地找到最优解。如果您需要在地图或网络中寻找最短路径,可以使用A算法来实现。