星型算法:使用启发式值作为连接器,其中节点具有相同的F值

时间:2018-05-24 23:25:44

标签: algorithm a-star heuristics

背景:我目前正在研究原始A Star算法的8-puzzle实现,并将其与略微修改的算法进行比较,该算法旨在改善节点扩展(使用附加信息,在同样知情的单向搜索中有A Star)被证明是最佳的)。节点的开放列表当前按其F值(G-Cost + H-Cost)排序。

因此,在Java中实现这一点时,我已经设置了一个比较器,它按照F值按升序对List进行排序。

       @Override
    public int compare(PNode o1, PNode o2) {
        return Integer.compare(o1.costF, o2.costF);
    }

问题:我的问题是:

  1. 在A-star下是否允许使用启发式成本(H值)在A-Star中实现进一步的连接断路器,以在许多节点(其中存在具有相同F的节点)中使用F值打破任何死锁 - 在开放列表中的值 - 它们将按启发式值(H-Cost)按升序排序)。之所以我对此感到困惑,因为实际的A star算法伪代码只能按F值对Open List进行排序。
  2. 扩展上面的相同代码,实现将是:

            @Override
        public int compare(PNode o1, PNode o2) {
            if (o1.costF == o2.costF) {
                return Integer.compare(o1.costH, o2.costH);
            }
            return Integer.compare(o1.costF, o2.costF);
        }
    
    1. 如果允许,有什么理由为什么我应该警惕这样做?从逻辑上讲,我很欣赏订购开放清单会更加昂贵。但是根据我的实验,差异似乎不足以阻止我使用它。
    2. 非常感谢大家〜

3 个答案:

答案 0 :(得分:2)

我认为这有两个原因

1)你只是改变了tie的行为,所以你所做的就是从原始版本可能的更大的执行路径集中选择一个可能的执行路径。

2)保留属性,如果从打开的List中检索目标节点,则open中的每个其他节点的G-Cost + H-Cost至少与刚刚检索到的节点一样昂贵,并且所以必须导致到目标节点的路径至少与刚刚检索到的节点一样昂贵。

在关系的情况下,通过支持具有低启发式成本的节点,在关系的情况下,你支持任何目标节点,所以我猜你可能会稍微提前检索目标节点,因此稍早完成。

答案 1 :(得分:2)

是的,这是允许的,几乎是出于mcdowella's answer中所述的原因。

但是,我想补充一点,这通常是一个非常好的主意,并且比答案中隐含的更有益。与仅仅稍早发现目标相比,这种打破平局可以导致更显着的性能提升。例如,参见this page,它可视化A *如何在没有打破平局的情况下探索相当大的区域,并且只有一条非常窄的带沿着最佳路径与打破平局。

直观地说,你可以通过思考不同级别的可靠性来理解它是如此有效。 G费用与H费用相比。 G成本是非常可靠的,它们是基本的事实,它们恰恰是您到达节点时必须付出的代价。 H成本不太可靠,它们是启发式的,它们可能是非常错误的。通过实施你提出的决胜局,你基本上是在说"只要两个节点具有相同的F = G + H值,我就更喜欢那些G更小H的节点}对于那些G和更高H" 的人。这是明智的,因为当G F组件更可靠H组件支配不太可靠的F组件时,firebase deploy本身也会更可靠。

另一个主要优点是,如我所链接的页面所描述的那样,这种打破平局可以避免探索大量不同路径的大部分,这些路径都是相同的并且都是最优的。

答案 2 :(得分:0)

启发式可以改变以保证更少的点具有相等的F [本文] 1

<块引用>

解决此问题的快速方法是调整 g 或 h 值。决胜局需要是确定性的 顶点(即它不应该是一个随机数),它需要 使 f 值不同。由于 A* 按 f 值排序,使它们 不同意味着只有一个“等效”的 f 值将是 探索。

打破平局的一种方法是稍微微调 h 的比例。如果我们缩放 它向下,那么随着我们朝着目标前进,f 将增加。 不幸的是,这意味着 A* 更愿意将顶点扩展为关闭 到起点而不是靠近目标的顶点。我们可以 相反,将 h 稍微向上缩放(甚至 0.1%)。 A* 会更喜欢 扩展靠近目标的顶点。

heuristic *= (1.0 + p)
dx1 = current.x - goal.x
dy1 = current.y - goal.y
dx2 = start.x - goal.x
dy2 = start.y - goal.y
cross = abs(dx1*dy2 - dx2*dy1)
heuristic += cross*0.001