我已经实现了A星算法来在简单网格上找到两个节点之间的路径。我目前正在一个没有障碍物的网格上进行测试,它似乎找到了一条最短的路径,但它并不是一条“理想的”最短路径,我的意思是不会随意改变方向。理想情况下,我希望它继续向一个方向前进,这意味着它只会改变方向一次。
我该如何强制执行此操作?我正在查看代码中我考虑在打开列表中展开哪个节点的部分,我可能能够通过记下前一个方向并选择相同方向来破解某些内容,如果下一个磁贴具有相同的f值,但它不是很优雅。
答案 0 :(得分:2)
根据您的图G=(V,E)
,其中v
中的每个V
代表一个单元格,并且每条边(u,v)
都可以移动,您可以创建一个新的(加权)图表G'=(V',E')
如下:
V' = V_u U V_d U V_l U V_r
- 每个组代表您上次执行的移动类型,V_u = { v_u | for each v in V }
代表V_d,V_l,V_r
现在,对于(u,v)
中的每个边E
:
(u_l,v_l,1)
和(u_r,v_l,1+eps),(u_u,v_l,1+eps),(u_d,v_l,1+eps)
。直观地 - 你为改变方向给予一个小的惩罚(eps),如果保持相同的方向则不会受到惩罚。(u_u,v_u,1)
和(u_r,v_u,1+eps),(u_l,v_u,1+eps),(u_d,v_u,1+eps)
。 (同样)确保eps
小到足以仅影响相同长度的路径。 1/(|V|+1)
应该这样做。
另外请确保您现在有4个目标(t_u,t_d,t_l,t_r
,其中t
是原始目标。)
这为您提供了一个带有4*|V|
个顶点的图形,现在有利于保持相同的方向而不是更改它。你可以坚持使用以前的启发式方法 - 如果它是可以接受的,它就会保持这种状态。
答案 1 :(得分:-1)
你不应该强制执行任何事情。只是看着你的路径,我可以看出你的算法存在问题。虽然没有你的代码,但我无法告诉你它在哪里。由于(a ^ 2 + b ^ 2 = c ^ 2),开放网格上的最短路径始终是直线。 A *将永远返回。如果您发布代码,我可以为您提供有关您需要做什么的指导。但是现在你的成本计算由于某种原因而被关闭,否则你会从头到尾直接前进。还要记住,A *在找到平局时找到最短路径之一。在你的情况下,不会有,但是当你添加障碍物时,视觉上评估图表并不总是一个好的指标。
长答案简短。检查您的成本函数以及您识别路径节点的上一个节点的方式。如果你发现将它带到当前节点是不利的,那么你就不会将前一个节点用于你的路径。如果您的成本函数是错误的(通常启发式方法会以某种方式搞乱),也会发生这种情况。