背景:我目前正在研究原始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);
}
问题:我的问题是:
扩展上面的相同代码,实现将是:
@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);
}
非常感谢大家〜
答案 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