【问题标题】:Understanding A* heuristics for single goal maze了解单目标迷宫的 A* 启发式
【发布时间】:2015-04-24 08:30:16
【问题描述】:

我有一个像下面这样的迷宫:

||||||||||||||||||||||||||||||||||||
|                                 P|
| ||||||||||||||||||||||| |||||||| |
| ||   |   |      |||||||   ||     |
| || | | | | |||| ||||||||| || |||||
| || | | | |             || ||     |
| || | | | | | ||||  |||    |||||| |
| |  | | |   |    || ||||||||      |
| || | | |||||||| ||        || |||||
| || |   ||       ||||||||| ||     |
|    |||||| |||||||      || |||||| |
||||||      |       |||| || |      |
|      |||||| ||||| |    || || |||||
| ||||||      |       ||||| ||     |
|        |||||| ||||||||||| ||  || |
||||||||||                  |||||| |
|+         ||||||||||||||||        |
||||||||||||||||||||||||||||||||||||

目标是P找到+,子目标为

  • + 的路径成本最低(1 跳 = 成本+1)
  • 搜索到的单元格数量(节点扩展)已最小化

我试图了解为什么我的 A* 启发式算法的性能比 Greedy Best First 的实现差得多。以下是每个代码的两位代码:

#Greedy Best First -- Manhattan Distance
self.heuristic = abs(goalNodeXY[1] - self.xy[1]) + abs(goalNodeXY[0] - self.xy[0])

#A* -- Manhattan Distance + Path Cost from 'startNode' to 'currentNode'
return abs(goalNodeXY[1] - self.xy[1]) + abs(goalNodeXY[0] - self.xy[0]) + self.costFromStart

在这两种算法中,我都使用heapq,根据启发式值进行优先级排序。两者的主要搜索循环是相同的:

theFrontier = []
heapq.heappush(theFrontier, (stateNode.heuristic, stateNode)) #populate frontier with 'start copy' as only available Node

#while !goal and frontier !empty
while not GOAL_STATE and theFrontier:
    stateNode = heapq.heappop(theFrontier)[1] #heappop returns tuple of (weighted-idx, data)
    CHECKED_NODES.append(stateNode.xy)
    while stateNode.moves and not GOAL_STATE:
        EXPANDED_NODES += 1
        moveDirection = heapq.heappop(stateNode.moves)[1]

        nextNode = Node()
        nextNode.setParent(stateNode)
        #this makes a call to setHeuristic
        nextNode.setLocation((stateNode.xy[0] + moveDirection[0], stateNode.xy[1] + moveDirection[1]))
        if nextNode.xy not in CHECKED_NODES and not isInFrontier(nextNode):
            if nextNode.checkGoal(): break
            nextNode.populateMoves()
            heapq.heappush(theFrontier, (nextNode.heuristic,nextNode))

所以现在我们来解决这个问题。虽然 A* 找到了 最佳 路径,但这样做的成本相当高。为了找到cost:68 的最佳路径,它会扩展(导航和搜索)452 个节点来执行此操作。

虽然我使用的 Greedy Best 实现仅在 160 次扩展中找到了一条次优路径(成本:74)。

我真的很想了解我在哪里出错了。我意识到 Greedy Best First 算法可以自然地表现出这样的行为,但节点扩展的差距是如此之大,我觉得这里有一些问题必须..任何帮助将不胜感激。如果我在上面粘贴的内容在某些方面不清楚,我很乐意添加详细信息。

【问题讨论】:

  • 别在意我以前的 cmets。这是完全正常的行为。我一开始以为 + 是开始。很难找到此类问题的最佳解决方案;这就是我们经常不打扰的原因。
  • 我发现的一件事并没有真正解决两者之间的差异,但确实提高了整体效率是在主循环的末尾添加以下内容:CHECKED_NODES.append(nextNode.xy) - 这似乎两种算法的扩展都减少了一半...

标签: python artificial-intelligence path-finding a-star heuristics


【解决方案1】:

A* 搜索试图找到问题的最佳解决方案,而贪婪的最佳优先则只是试图找到任何解决方案。 A* 有一个非常非常艰巨的任务,它必须投入大量工作来探索可能是最佳的每一条路径,而贪婪的最佳优先算法只是直接寻找看起来最接近目标的选项.

【讨论】:

    【解决方案2】:

    A* 提供问题的最佳答案,贪婪的最佳优先搜索提供任何解决方案。

    预计 A* 必须做更多的工作。

    如果您想要 A* 的变体不再是最优但返回解决方案的速度要快得多,您可以查看加权 A*。它只是包括给启发式赋予权重(权重> 1)。在实践中,它会给你带来巨大的性能提升

    例如,你可以试试这个:

    return 2*(abs(goalNodeXY[1] - self.xy[1]) + abs(goalNodeXY[0] - self.xy[0])) + self.costFromStart
    

    【讨论】:

      【解决方案3】:

      由于这个问题尚未解决,即使 OP 提出的有问题可以用Fezvez's answer 解决,我觉得我需要问这个问题,也许可以回答问题所在为什么 Fezvez 的回答可以解决这个问题:您是否使用 A* 算法检查了所有节点的启发式值并注意到一些奇怪的东西?他们不都是平等的吗?因为即使您的启发式对于最佳优先算法是正确的,但它并不直接适合您的 A* 算法。我在java中做了一个类似的项目,我遇到了这个问题,这就是我在这里问的原因。例如,假设您有以下兴趣点:

      • 开始(P) - (0,0)
      • 结束(+) - (20,20)
      • P1 - (2,2) -> (你的启发式) + (路径成本) = ((20-2) + (20-2)) + ((2-0) + (2-0)) = 40
      • P2 - (4,3) -> (你的启发式) + (路径成本) = ((20-4) + (20-3)) + ((4-0) + (3-0)) = 40

      而且,如果我没记错的话,这对于你在迷宫中的所有点都是正确的。现在,考虑到 A* 算法通常像具有启发式(和路径成本)的广度优先算法一样实现,因为您的启发式总是给您相同的总数 (F = h+g)实际上变成了一种广度优先算法,它也为您提供了可能的最佳解决方案,但实际上总是比 A* 通常慢。现在,正如 Fezvez 所建议的那样,赋予您的启发式权重可能只是混合了两全其美(最佳优先和广度优先),并且看起来像上面给出的点:

      • 开始(P) - (0,0)
      • 结束(+) - (20,20)
      • P1 - (2,2) -> 2*(你的启发式) + (路径成本) = 2*((20-2) + (20-2)) + ((2-0) + (2- 0)) = 76
      • P2 - (4,3) -> 2*(你的启发式) + (路径成本) = 2*((20-4) + (20-3)) + ((4-0) + (3- 0)) = 73

      【讨论】:

        猜你喜欢
        • 2019-06-20
        • 1970-01-01
        • 1970-01-01
        • 2011-09-22
        • 2015-07-03
        • 2020-06-14
        • 1970-01-01
        • 2019-02-01
        • 2022-01-13
        相关资源
        最近更新 更多