简体   繁体   English

对角启发式A *算法中的怪异行为

[英]Weird behavior in A* algorithm with diagonal heuristic

I'm playing with the A* algorithm, so I can take a picture of a maze with a webcam and have a program solve it. 我正在使用A *算法,因此可以使用网络摄像头拍摄迷宫的照片,并使用程序来解决它。 Here are the results: 结果如下: http://i.stack.imgur.com/lbmKg.png

When I use h = 0, I get a nice solution. 当我使用h = 0时,我得到一个很好的解决方案。 Using manhattan distance also gives a good solution. 使用曼哈顿距离也提供了很好的解决方案。 However, diagonal distance does some weird things, like the pattern that I circled in green. 但是,对角线距离会做一些奇怪的事情,例如我以绿色圈出的图案。 Or even more weird is this one, from a different maze: 甚至更奇怪的是,来自另一个迷宫的那个:

http://i.stack.imgur.com/dTzyr.png

Did I wrongly implement the diagonal distance? 我是否错误地实现了对角线距离?

public void findHeuristic()
{
    int dx = Math.abs(x - MazeBot.goal.x);
    int dy = Math.abs(y - MazeBot.goal.y);

    h = 10 * (dx + dy) - 6 * Math.min(dx, dy); //diagonal distance
}

I haven't heard the term "diagonal distance" before, but I think I see what you're getting at -- you're measuring how many "jumps" it would take where you can jump vertically, horizontally, or diagonally. 我以前从未听说过“对角线距离”一词,但我想我明白了,您正在测量要在垂直,水平或对角线上跳跃所需的“跳跃数”。 What I can't figure out is why where your coefficients are coming from, unless you're wanting to weight the jumps by the length of the move. 我无法弄清楚的是为什么您的系数来自何处,除非您想根据移​​动的长度来加权跳跃。 In which case, you're just starting to approximate a Euclidean metric. 在这种情况下,您只是开始近似欧几里得度量。

So, assuming every 'jump' is the same size: dx + dy - Math.min(dx, dy) 因此,假设每个“跳跃”的大小相同: dx + dy - Math.min(dx, dy)

However, noting that diagonal jobs are actually sqrt(2) length, you'd end up with (dx + dy) - (2 - Math.sqrt(2)) * Math.min(dx, dy) . 但是,注意到对角线作业实际上是sqrt(2)长度,所以最终得到(dx + dy) - (2 - Math.sqrt(2)) * Math.min(dx, dy) That's about (dx + dy) - 0.5857 * Math.min(dx, dy) . 大约是(dx + dy) - 0.5857 * Math.min(dx, dy) I assume you're wanting to keep to integers and no division for speed and efficiency, and since if the output is scaled by a positive constant it won't change the utility of your heuristic, you just chose some very close coefficients by multiplying everything by 10: 10 * (dx + dy) - 5.857 * Math.min(dx, dy) is about 10 * (dx + dy) - 6 * Math.min(dx, dy)' . 我假设您想保留整数,并且不对速度和效率进行除法,并且由于如果输出按正常数进行缩放,则不会改变启发式方法的效用,因此您只需乘以所有乘积就可以选择一些非常接近的系数乘10 * (dx + dy) - 5.857 * Math.min(dx, dy)约为10 * (dx + dy) - 6 * Math.min(dx, dy)' (What you have now.) (您现在拥有的。)

Since you've created a finer approximation of the Euclidean metric, your paths will tend to necessarily assume more direct lines to the goal(s). 由于您已经创建了欧几里得度量的更好的近似值,因此您的路径将趋向于必然要采用指向目标的更多直线。 However, since your approximation is in fact an approximation of an approximation, you're going to end up with some strange results: 但是,由于您的近似值实际上是近似值的近似值,因此您最终将得到一些奇怪的结果:

The greater your Math.min(dx, dy) the greater your error since 6 > 5.857 you're effectively making the diagonal paths less costly that it should be, but as you get closer to them non-diagonal paths start to measure relatively better. 6 > 5.857以来Math.min(dx, dy)越大,您的误差越大,您6 > 5.857在使对角线路径的成本降低了,但随着距它们的距离越来越近,非对角线路径开始相对更好地进行测量。 This isn't leading to a truly less optimal path, per se, but I'd expect it to create some difficult-to-predict strangeness in your traversal. 从本质上讲,这并不会导致真正不那么理想的路径,但是我希望它会在遍历中产生一些难以预测的陌生性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM