我在使用A*搜索算法实现《弹跳机器人》游戏。游戏的目标是将特定的机器人移动到棋盘上的特定位置。棋盘上可能有多个墙壁,并且还有其他三个机器人可以移动。
我目前使用曼哈顿距离作为启发式函数,但这种方法在某些情况下无法正常工作,有时会陷入无限循环。我认为这是因为棋盘上存在障碍物的缘故。
在这种情况下,最佳的启发式函数是什么?
这是A*搜索函数的代码。它接收启发式函数作为输入。节点是一个对象,包含当前状态和当前棋盘的信息。
def astar_search(problem, h, display=False): h = memoize(h or problem.h, 'h') return best_first_graph_search(problem, lambda n: n.path_cost + h(n), display)def best_first_graph_search(problem, f, display=False): f = memoize(f, 'f') node = Node(problem.initial) frontier = PriorityQueue('min', f) frontier.append(node) explored = set() while frontier: node = frontier.pop() if problem.goal_test(node.state): if display: print(len(explored), "paths have been expanded and", len(frontier), "paths remain in the frontier") return node explored.add(node.state) for child in node.expand(problem): if child.state not in explored and child not in frontier: frontier.append(child) elif child in frontier: if f(child) < frontier[child]: del frontier[child] frontier.append(child) return None
回答:
A*使用的启发式函数绝不能高估成本。由于在《弹跳机器人》中,一个移动可以移动任意距离,曼哈顿距离作为启发式函数是行不通的。
我能想到的唯一有效的启发式函数是“如果不在同一行或同一列,则为2;否则如果不是最终目标,则为1”,因为无法进行对角线移动。