[英]Shortest path from Start to end point using BFS
如果存在从表示为S
的给定起点到端点E
的最短路径,我想显示最短路径。 我有一个矩阵,其值为0
表示没有路径, 1
表示访问的有效路径。 我可以按行和按列访问,但不能按对角线方式访问。 现在使用 BFS,我可以使用以下代码将最短路径值作为整数获取:
public static void main(String[] args) {
int r = findShortestPathBFS(new char[][] { "0001110011".toCharArray(), "1111011110".toCharArray(),
"0110001010".toCharArray(), "S010101011".toCharArray(), "1110111E01".toCharArray() }, 3, 0);
System.out.println(r);
}
private static int findShortestPathBFS(char arr[][], int startX, int startY) {
if (arr[startX][startY] == 'E')
return 0;
int moveX[] = new int[] { 0, 0, 1, -1 };
int moveY[] = new int[] { 1, -1, 0, 0 };
boolean visited[][] = new boolean[arr.length][arr[0].length];
Queue<QNode> qNodes = new LinkedList<>();
qNodes.add(new QNode(startX, startY, 0));
while (!qNodes.isEmpty()) {
QNode currNode = qNodes.remove();
int currX = currNode.x;
int currY = currNode.y;
int currDistance = currNode.distance;
visited[currX][currY] = true;
// System.out.println(arr[currX][currY]);
if (arr[currX][currY] == 'E')
return currDistance;
for (int i = 0; i < moveX.length; i++) {
int newX = currX + moveX[i];
int newY = currY + moveY[i];
if (newX >= 0 && newX < arr.length && newY >= 0 && newY < arr[0].length && !visited[newX][newY]
&& arr[newX][newY] != '0') {
qNodes.add(new QNode(newX, newY, currDistance + 1));
}
}
}
return -1;
}
private static class QNode {
int x;
int y;
int distance;
QNode(int x, int y, int distance) {
this.x = x;
this.y = y;
this.distance = distance;
}
}
在这个例子中,输入是:
0001110011
1111011110
0110001010
S010101011
1110111E01
[3,0]
是我的起点, [4,7]
是我的目的地,值为E
上面的代码将16
打印为最短路径。 但是如果无法到达目的地,我想打印这样的实际路径(如果存在或not exists
。
上述代码的预期输出:
000***0011
11**0**110
01*000*010
S0*010*011
***011*E01
在这里,我想使用带有*
有效路径路线再次打印矩阵。 如何在我的代码中实现这一点,或者是否有更好的方法来解决这个问题?
你可以在你的类 QNode 中有一个名为 prev 的字段来跟踪它访问的前一个节点,当你完成搜索时,你可以通过跟随 prev 链接来跟踪你的路径。
代码将是:
private static Queue<QNode> qNodes;
private static QNode endNode;
public static void main(String[] args) {
char[][] M = new char[][] { "0001110011".toCharArray(), "1111011110".toCharArray(),
"0110001010".toCharArray(), "S010101011".toCharArray(), "1110111E01".toCharArray() };
int r = findShortestPathBFS(M, 3, 0);
while ( endNode.prev != null && M[endNode.prev.x][endNode.prev.y] != 'S') {
M[endNode.prev.x][endNode.prev.y] = '*';
endNode = endNode.prev;
}
for ( char[] arr : M )
System.out.println(Arrays.toString(arr));
}
private static int findShortestPathBFS(char arr[][], int startX, int startY) {
if (arr[startX][startY] == 'E')
return 0;
int moveX[] = new int[] { 0, 0, 1, -1 };
int moveY[] = new int[] { 1, -1, 0, 0 };
boolean visited[][] = new boolean[arr.length][arr[0].length];
qNodes = new LinkedList<>();
qNodes.add(new QNode(startX, startY, 0, null));
while (!qNodes.isEmpty()) {
QNode currNode = qNodes.remove();
int currX = currNode.x;
int currY = currNode.y;
int currDistance = currNode.distance;
visited[currX][currY] = true;
// System.out.println(arr[currX][currY]);
if (arr[currX][currY] == 'E') {
endNode = currNode;
return currDistance;
}
for (int i = 0; i < moveX.length; i++) {
int newX = currX + moveX[i];
int newY = currY + moveY[i];
if (newX >= 0 && newX < arr.length && newY >= 0 && newY < arr[0].length && !visited[newX][newY]
&& arr[newX][newY] != '0') {
qNodes.add(new QNode(newX, newY, currDistance + 1, currNode));
}
}
}
return -1;
}
private static class QNode {
int x;
int y;
int distance;
QNode prev;
QNode(int x, int y, int distance, QNode prev) {
this.x = x;
this.y = y;
this.distance = distance;
this.prev = prev;
}
}
看到我将队列移到外面并使用一个名为 endNode 的节点来跟踪井端节点,然后在搜索该 endNode 是否为空后,即如果找到,则使用其上一个链接进行跟踪,直到它为空。 从语句中可以看出,起始节点为空: qNodes.add(new QNode(startX, startY, 0, null));
输出是:
[0, 0, 0, *, *, *, 0, 0, 1, 1]
[1, 1, *, *, 0, *, *, 1, 1, 0]
[0, 1, *, 0, 0, 0, *, 0, 1, 0]
[S, 0, *, 0, 1, 0, *, 0, 1, 1]
[*, *, *, 0, 1, 1, *, E, 0, 1]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.