曼哈顿距离A *

时间:2012-09-21 08:23:46

标签: java artificial-intelligence a-star 8-puzzle

我正在使用A *搜索算法实现一个NxN拼图求解器,并使用曼哈顿距离作为启发式,我遇到了一个好奇的 bug (?)我无法绕过头脑

考虑这些谜题(0元素为空格):
(初始)

1 0 2
7 5 4
8 6 3

(目标)的

1 2 3
4 5 6
7 8 0

从初始状态到达解决方案的最小移动次数为11.但是,我的求解器在17次移动中达到目标。

其中存在问题 - 我的解谜手段主要解决了正确(最小)移动数量的可解决难题,但对于这个特殊难题,我的求解者超过最小移动次数,我想我已经解决了问题在这种特殊情况下错误估算曼哈顿距离。

在这个link你可以看到我的求解器在做什么(在右边)以及经过试验的求解器正在做什么(Brian Borowski的优秀求解器,可用here)。

在第一步中,Brian的解算器立即选择推动元素5的解决方案,但我的解算器有其他想法,并且在堆栈跟踪(在link上给出),我的求解器选择推送2的解决方案左边(由于该板的曼哈顿距离较低,因此该板位于优先级队列的前面)。 我看不出有什么问题,我不能责怪我的曼哈顿距离计算,因为它正确地解决了许多其他3x3难题。

以下是我如何计算给定董事会的曼哈顿距离:

/**
 * Calculates sum of Manhattan distances for this board and stores it in private field to promote immutability.
 */
private void calculateManhattanDistance() {
    int manhattanDistanceSum = 0;
    for (int x = 0; x < N; x++) // x-dimension, traversing rows (i)
        for (int y = 0; y < N; y++) { // y-dimension, traversing cols (j)
            int value = tiles[x][y]; // tiles array contains board elements
            if (value != 0) { // we don't compute MD for element 0
                int targetX = (value - 1) / N; // expected x-coordinate (row)
                int targetY = (value - 1) % N; // expected y-coordinate (col)
                int dx = x - targetX; // x-distance to expected coordinate
                int dy = y - targetY; // y-distance to expected coordinate
                manhattanDistanceSum += Math.abs(dx) + Math.abs(dy); 
            } 
        }
    manhattanDistance = manhattanDistanceSum;
}

我很感激您的任何见解或想法。

如果需要任何其他代码,我会立即发布。

2 个答案:

答案 0 :(得分:3)

我被困在同一个地方的某个地方,我在17次移动中解决了这个问题。问题是我只使用启发式h(n)进行A *算法,而选择下一个节点时A *使用曼哈顿距离(启发式)+ pathcost(从根到达节点的成本称为g(n))来做出选择。 一旦你将其插入到算法中,它就像一个魅力。

希望这可以帮助那些被困在同一个地方的人。

答案 1 :(得分:1)

如果你的启发式是可以接受的(并且它是,检查this)而不是A *总是返回最佳解决方案。可以更慢或更快(扩展更多或更少的节点),但它返回最佳解决方案。

因此,因为必须在A *算法实现中,您的启发式是可以接受的。

此外,它的第一步与最佳步骤不同的事实是没有意义的:算法可以正确执行回溯以在将来获得正确的解决方案路径。所有开放节点都是下一步的候选节点,而不仅仅是当前节点的子节点。