嗨,我正在研究这个小项目,需要我在Java中构建一个类似棋盘的矩阵。我应该让骑士从一个点到另一个点(在Knight移动的方式)。所以我需要找到最终到达目的地的最短路径。
我的问题是,我无法连接边缘以达到这一点。我可以看出顶点是否是一个有效的移动,但我似乎无法找到一种方法来创建节点来达到这一点。例如,
0 XXXXX
1 XXXOX
2 XXXXX
3 XXKXX
4 XXXXX
5 XXXXX
我需要创建将K连接到O的节点,以便稍后查找最短距离。 PS。我会很好,只是提示如何到达那里或只是一些提示。真的不需要确切的代码。非常感谢你! 我知道这是矩阵的一个不好的代表,但请不要批评我
答案 0 :(得分:0)
国际象棋棋盘可以用2d阵列实现。矩阵中的每个单元可以被认为是图中的节点(或顶点)。 Edge由两个节点组成(在本例中为两个单元格),一个是from
或source
[让我们称之为Nod A],另一个是to
或neighbor
或destination
节点[让我们称之为节点B]。
如果有可能从node A
转移到node B
,则会退出边缘。
您可以使用Dijkstra's algorithm
。
http://krishnalearnings.blogspot.in/2015/07/implementation-in-java-for-dijkstras.html
对于具有骑士位置的节点,您可以看到Knight可以移动到并在Min Heap中添加的单元格的可能性。每个边缘的重量是恒定的。您只需要更新节点的成本。
答案 1 :(得分:0)
经典Breadth-First-Search可能是最简单的方法:
class Location {
int x;
int y;
List<Location> adjacent() {
// TODO return list of locations reachable in a single step
}
}
List<Location> findShortestPath(Location start, Location destination) {
Location[][] previous = new Location[8][8];
Deque<Location> queue = new ArrayDeque<>();
queue.add(start);
do {
Location loc = queue.poll();
for (Location n : loc.neighbors()) {
if (previous[n.x][n.y] == null) {
previous[n.x][n.y] = loc;
queue.add(n);
if (n.x == destination.x && n.y == destination.y) {
// we've found a way, let's reconstruct the list of steps
List<Location> path = new ArrayList<>();
for (Location l = n; l != start; l = previous[l.x][l.y]) {
path.add(l);
}
path.reverse();
return path;
}
}
}
} while (!queue.isEmpty());
return null; // no path exists
}
此代码枚举从起始位置开始的所有路径。因此,如果有目的地的路径,它将找到它。另外,因为路径按顺序或上升长度枚举,所以第一个这样的路径将是最短路径。