A*算法中的曼哈顿距离

我在使用A*搜索算法实现NxN拼图解算器,并使用曼哈顿距离作为启发式函数时,遇到了一个奇怪的bug(?),我无法理解它。

考虑这些拼图(0元素表示空白空间):
(初始状态)

1 0 2
7 5 4
8 6 3

(目标状态)

1 2 3
4 5 6
7 8 0

从初始状态达到解决方案的最小移动次数是11。然而,我的解算器在17步后达到了目标状态。

问题就出在这里 – 我的拼图解算器通常能以正确(最少)的移动次数解决可解的拼图,但对于这个特定的拼图,我的解算器超出了最小的移动次数,我认为我已经确定了问题所在,即在这种特定情况下曼哈顿距离的计算错误。

在这个链接上,你可以看到我的解算器在做什么(右侧),以及一个经过验证的解算器在做什么(Brian Borowski的优秀解算器,可在此处获取)。

在第一步,Brian的解算器立即选择了将元素5向上推的解决方案,但我的解算器有不同的想法,在堆栈跟踪(在链接上给出)中,我的解算器选择了将2向左推的解决方案(因为那个棋盘的曼哈顿距离更低,该棋盘位于优先级队列的前端)。我看不出问题出在哪里,也不能责怪我的曼哈顿距离计算,因为它正确地解决了许多其他3×3拼图。

这是我如何计算给定棋盘的曼哈顿距离:

/** * 计算此棋盘的曼哈顿距离之和,并将其存储在私有字段中以促进不可变性。 */private void calculateManhattanDistance() {    int manhattanDistanceSum = 0;    for (int x = 0; x < N; x++) // x维度,遍历行(i)        for (int y = 0; y < N; y++) { // y维度,遍历列(j)            int value = tiles[x][y]; // tiles数组包含棋盘元素            if (value != 0) { // 我们不计算元素0的MD                int targetX = (value - 1) / N; // 预期的x坐标(行)                int targetY = (value - 1) % N; // 预期的y坐标(列)                int dx = x - targetX; // 到预期坐标的x距离                int dy = y - targetY; // 到预期坐标的y距离                manhattanDistanceSum += Math.abs(dx) + Math.abs(dy);             }         }    manhattanDistance = manhattanDistanceSum;}

我很感激你能提供任何见解或想法。

如果需要更多代码,我会立即发布。


回答:

我之前也曾卡在同样的地方,当时我在17步内解决了这个问题。问题在于我只使用了启发式函数h(n)来进行A*算法,而在选择下一个节点时,A*使用曼哈顿距离(启发式函数)+路径成本(从根节点到达该节点的成本,称为g(n))来做出选择。一旦你将这个因素加入算法中,它就会运作得非常好。

希望这能帮助那些卡在同样问题上的人。

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注