我最近在Lua中实现了A *寻路,但由于在成本中使用了曼哈顿方法,我遇到了错误的路径。
我想知道是否有其他计算节点成本的方法。以下是我目前使用的内容:
function CalcG(A,B)
if type(A) == "table" then
A = A.Pos
end
if type(B) == "table" then
B = B.Pos
end
return (A-B).Magnitude
end
function CalcH(A,B)
if type(A) == "table" then
A = A.Pos
end
if type(B) == "table" then
B = B.Pos
end
return math.abs(A.X - B.X) + math.abs(A.Z - B.Z)
end
function GetCost(A,B,C)
return CalcG(A,B) + CalcH(B,C)
end
计算成本:
GetCost(Start,CurrentNode,End)
如果有人能指导我采用更好的启发式方法,我将不胜感激。
答案 0 :(得分:0)
(注:WuTangTan在评论中所说的内容仍然适用;这看起来像是你实施中的一个错误)
只要启发式允许,或者不高估路径的实际成本,就可以保证正确的A *实现找到最短路径(有关详细信息,请参阅Wikipedia's entry on A* )。对于无法沿对角线移动的网格,曼哈顿距离符合此标准。但从你的形象判断,看起来你也可以对角移动,所以曼哈顿距离不再准确地判断距离。考虑一下这张照片:
蓝色是曼哈顿距离,绿色是'正确'距离。
如您所见,当我们添加对角移动的能力时,两点之间的距离变短。曼哈顿距离现在高估了距离,现在不允许,导致A *并不总是找到最短的路径。
那么我们可以用一种启发式来模拟对角网格运动吗?你打赌!它叫做 Chebyshev distance 。它考虑了对角线的移动,因此在这种情况下建模距离要好得多。想想棋盘上的国王。
它的实现很简单:
function chebyshevDistance(dx, dy)
return math.max(dx, dy)
end