在我的第二次尝试中,我成功计算出追溯所需的所有值。同时用S标记起始单元格,用B标记阻塞的单元格,用F标记目标单元格。
现在回溯时,我将从目标单元格开始跟随最低G值的单元格。
这里我会跟随G = 24 => G = 10 => S。
正如您所看到的,该解决方案会创建一条无效的路径,因为它穿过了墙壁。
这与在计算网格的值时角落切割有关。如您在此处所见。我们应该回溯:G = 50 => G = 40,然后接下来选G = 20。这导致了角落切割。
我认为这个问题出现在计算每个相邻单元格的值时。如果我在添加相邻单元格到当前单元格时设置一些限制,或许可以避免这种情况?
现在回溯时,我将从目标单元格开始跟随最低G值的单元格。
这里我会跟随G = 24 => G = 10 => S。
正如您所看到的,该解决方案会创建一条无效的路径,因为它穿过了墙壁。
这与在计算网格的值时角落切割有关。如您在此处所见。我们应该回溯:G = 50 => G = 40,然后接下来选G = 20。这导致了角落切割。
我认为这个问题出现在计算每个相邻单元格的值时。如果我在添加相邻单元格到当前单元格时设置一些限制,或许可以避免这种情况?
public List<Cell> GetAdjacent(Cell _currentCell, List<Cell> _closedList, List<Cell> _gridList)
{
List<Cell> adjacentList = new List<Cell>();
List<Cell> gridList = _gridList;
List<Cell> closedList = _closedList;
Cell currentCell = _currentCell;
foreach (Cell cell in gridList)
{
bool containedInClosedList = closedList.Any(c => c.id == cell.id);
if (!cell.blocked && !containedInClosedList &&
((cell.positionCR.X == currentCell.positionCR.X - 1 && cell.positionCR.Y == currentCell.positionCR.Y) ||
(cell.positionCR.X == currentCell.positionCR.X + 1 && cell.positionCR.Y == currentCell.positionCR.Y) ||
(cell.positionCR.X == currentCell.positionCR.X && cell.positionCR.Y == currentCell.positionCR.Y - 1) ||
(cell.positionCR.X == currentCell.positionCR.X && cell.positionCR.Y == currentCell.positionCR.Y + 1) ||
(cell.positionCR.X == currentCell.positionCR.X - 1 && cell.positionCR.Y == currentCell.positionCR.Y - 1) ||
(cell.positionCR.X == currentCell.positionCR.X - 1 && cell.positionCR.Y == currentCell.positionCR.Y + 1) ||
(cell.positionCR.X == currentCell.positionCR.X + 1 && cell.positionCR.Y == currentCell.positionCR.Y - 1) ||
(cell.positionCR.X == currentCell.positionCR.X + 1 && cell.positionCR.Y == currentCell.positionCR.Y + 1)))
{
adjacentList.Add(cell);
}
}
return adjacentList;
}
这可能与我定义的定制成本有关吗?我为直线选了G=10,对角线选了G=14。
我认为这是阻止我完成算法的最后一件事,因此我期待任何帮助或建设性的意见。
提前感谢!
A*
算法要求其正确性的近似度量低估到目标的距离。如果您使用欧几里得度量作为近似度量,则可能会高估14和10乘以根号2之间的差异,约为1%。这样微小的高估不太可能产生非常糟糕的结果,但值得考虑是否有更好的加权方式可以保持指标可接受。 - Eric Lippert