gpt4 book ai didi

java - 在java中使用递归来解决迷宫问题

转载 作者:太空宇宙 更新时间:2023-11-04 12:22:53 25 4
gpt4 key购买 nike

我尝试了这个问题,但由于某种原因,结果不正确。给定一组字符串,找出迷宫中存在多少种可能的解决方案,其中字符串由一个“R”(老鼠)、一个“C”(奶酪)、多个“X”(无法通过的方 block )和“.”(可能的路径)组成。任务是找出老鼠到达奶酪时可以采取的可能路线数,而不会增加其路径上任何点与奶酪之间的(欧几里得)距离。我的代码看起来有什么问题吗?

public class RatRoute { 
private static String[] enc;
private static int count;
private static int[] r;
private static int[] c;

// Test the program
public static void main(String[] args) {
String[] test = {
".R...",
"..X..",
"....X",
"X.X.X",
"...C."};
int num1 = numRoutes(test);
System.out.println(num1);
}

// Set variables, and call recursive function
public static int numRoutes(String[] enc) {
RatRoute.enc = enc;
r = findR(enc);
c = findC(enc);
recursiveHelper(r[0], r[1]);
return count;
}

// Recursive
public static void recursiveHelper(int x, int y) {

/*System.out.println();
System.out.println();
for (int k = 0; k < enc.length; k++) {
System.out.println(enc[k]);
}*/

if(isBlock(x,y)) {
return;
} else if (isBigger(x,y)) {
return;
} else if (isCheese(x, y)) {
count++;
//System.out.println("Found the Cheese! Path number: " + count);
//System.out.println();
return;
}

enc[x] = currentPath(x,y);
recursiveHelper(x + 1, y);
recursiveHelper(x, y + 1);
recursiveHelper(x, y - 1);
recursiveHelper(x - 1, y);
enc[x] = returnPath(x,y);

}

// Change the most recently traveled coordinates into a block
public static String currentPath(int x, int y) {
char[] Chars = enc[x].toCharArray();
Chars[y] = 'X';
String newString = String.valueOf(Chars);
return newString;
}

// Turn path already traveled from blocks back into a usable path to travel (undo the currentPath method)
public static String returnPath(int x, int y) {
char[] Chars = enc[x].toCharArray();
Chars[y] = '.';
String newString = String.valueOf(Chars);
return newString;
}

// Check if the next movement is into the cheese
public static boolean isCheese(int x, int y) {
if (enc[x].charAt(y) == 'C') {
return true;
} else {
return false;
}
}

// Check if the next movement is into a block, or outside the given array
public static boolean isBlock(int x, int y) {
if (x == -1 || y == -1
|| x >= enc.length || y >= enc[x].length()) {
return true;
} else if (enc[x].charAt(y) == 'X') {
//System.out.println(x + "," + y);
return true;
} else {
return false;
}
}

// See if the distance between the rat and the cheese has gotten larger or smaller
public static boolean isBigger(int x, int y) {
double rx = r[0]; double ry = r[1];
double cx = c[0]; double cy = c[1];

double originalDist = Math.sqrt(Math.pow(rx-cx, 2) + Math.pow(ry-cy, 2));
double newDist = Math.sqrt(Math.pow(x-cx, 2) + Math.pow(y-cy, 2));

//System.out.println("Orginal Distance: " + originalDist);
//System.out.println("New Distance: " + newDist);

if (newDist > originalDist) {
return true;
} else {
return false;
}
}

// Find the variables for the original position of the rat
public static int[] findR(String[] enc) {
for (int i = 0; i < enc.length; i++) {
for (int j = 0; j < enc[i].length(); j++) {
if (enc[i].charAt(j) == 'R') {
int[] coordinates = {i, j};
//System.out.println(coordinates[0] + "," + coordinates[1]);
return coordinates;
} else {

}
}
}
int[] other = {-1, -1};
return other;
}

// Find the variables for the original position of the rat
public static int[] findC(String[] enc) {
for (int i = 0; i < enc.length; i++) {
for (int j = 0; j < enc[i].length(); j++) {
if (enc[i].charAt(j) == 'C') {
int[] coordinates = {i, j};
//System.out.println(coordinates[0] + "," + coordinates[1]);
return coordinates;
} else {

}
}
}
int[] other = {-1, -1};
return other;
}

}

最佳答案

让我们从一个有用的观察开始:

[...] without ever increasing the (Euclidean) distance between itself and the cheese at any point on its path.

基本上,这意味着每当老鼠靠近奶酪时,它就永远不会回到更远的位置。

因此,假设老鼠 x 坐标为 3,奶酪 x 坐标为 5,则老鼠无法“向左走”(即 x = 2),因为这会导致它比之前距离奶酪更远。

因此,简化问题的一个好方法是找到老鼠可以走的方向。在您的示例中,老鼠位于奶酪的左上方,因此它只能向下或向右移动,否则它会离奶酪更远。当老鼠x与奶酪x匹配时,它将无法再向右或向左移动,y也是如此。

使用您的代码,如果:

r[0] - c[0] = 0 // the rat cannot move on the x any more.
r[1] - c[1] = 0 // the rat cannot move on the y any more.

什么时候

r[0] - c[0] == 0 && r[1] - c[1] == 0

老鼠到达了奶酪!在这种情况下,我们可以增加计数器,因为找到了成功的路由。

现在让我们通过递归来实践这一点。从您发布的代码中,我们从给定的 c(使用 findC(enc) 找到)和给定的 r(使用 findR(enc) 找到)开始

因此递归方法如下所示:

private void findRoutesFrom(int[] r) {
// what directions can the rat go?
// if the cheese is on the right of the mouse, xDirection
// would be +1.
int xDirection = (int) Math.signum(c[0] - r[0]);
// if the cheese is below of the mouse, yDirection
// would be +1.
int yDirection = (int) Math.signum(c[1] - r[1]);

// Now, if xDirection is != 0 the rat can attempt to move
// in that direction, checking if there's not a block
if(xDirection != 0 && !isBlock(r[0] + xDirection, r[1])) {
// if it can move in that direction, then use recursion to
// find all the possible paths form the new position
findRoutesFrom(new int[]{r[0] + xDirection, r[1]});
}

// same goes for yDirection
if(yDirection != 0 && !isBlock(r[0], r[1] + yDirection)) {
findRoutesFrom(new int[]{r[0], r[1] + yDirection});
}

// if the rat reaches the cheese, increase the successful
// paths counter
if(xDirection == 0 && yDirection == 0) {
count++;
}
}

就是这样!由于 Eculedean 距离约束,检查方向是否为 != 0 就足够了,因为当方向为 false 时,老鼠就无法再沿该方向移动。

关于java - 在java中使用递归来解决迷宫问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38649044/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com