如何解决深度优先搜索递归调用导致StackOverflow错误
为了解决迷宫,我使用深度优先搜索算法的实现方式进行了迷宫。我不希望找到最短的路径,而是希望找到有效路径的最快方法。这是我用来解决迷宫的方法。迷宫是2d个int数组,其中0是空心正方形,1是墙壁,2是访问过的正方形,9是目的地。 public class DepthAlgorithm {
/**
* This method returns true when a path is found. It will also fill up the
* list with the path used. It will start from (xn,yn,.....,x2,y2,x1,y2)
* because it will use recursion.
* @param maze 2d array of maze
* @param x the x of the starting position
* @param y the y of the starting position
* @param path a List of the path
* @return True if a path is found
*/
public static boolean searchPath(int [][] maze,int x,int y,List<Integer> path){
// Check if the destination (9) is reached
if (maze[y][x] == 9) {
path.add(x);
path.add(y);
return true;
}
// When the current position is not visited (0) we shall make it visited (2)
if (maze[y][x] == 0) {
maze[y][x] = 2;
//Here we visit all neighbour squares recursively and if a path is found
// we shall fill the path list with the current position.
int dx = -1; // Start and search from starting
int dy = 0; // position (x-1,y)
if (searchPath(maze,x + dx,y + dy,path)) {
path.add(x);
path.add(y);
return true;
}
dx = 1; // Start and search from starting
dy = 0; // position (x+1,path)) {
path.add(x);
path.add(y);
return true;
}
dx = 0; // Start and search from starting
dy = -1; // position (x,y-1)
if (searchPath(maze,path)) {
path.add(x);
path.add(y);
return true;
}
dx = 0; // Start and search from starting
dy = 1; // position (x,y+1)
if (searchPath(maze,path)) {
path.add(x);
path.add(y);
return true;
}
}
return false;
}
}
我的算法适用于小迷宫大小。当我想解决一个50 * 50的迷宫时,它很快。当我移至500 * 500时,出现堆栈溢出错误。我可以理解它是由于函数的许多递归调用而出现的,但是我不知道如何解决它。 有没有其他方法可以使我仍然可以使用深度优先搜索并存储路径,但是没有堆栈溢出?还是可以对我的代码进行任何更改,以便对其进行修复?
public class MazeRunner {
// Maze is a 2d array and it has to be filled with walls peripherally
// with walls so this algorithm can work. Our starting position in this
// will be (1,1) and our destination will be flagged with a 9 which in
// this occasion is (11,8).
private int[][] maze ;
private final List<Integer> path = new ArrayList<>();
public long startTime,stopTime;
public MazeRunner(int [][] maze){
this.maze = maze;
}
public void runDFSAlgorithm(int startingX,int startingY){
startTime = System.nanoTime();
DepthAlgorithm.searchPath(maze,startingX,startingY,path);
stopTime = System.nanoTime();
printPath();
System.out.println("Time for Depth First Algorithm: "+((double) (stopTime-startTime) / 1_000_000)+" milliseconds");
}
public void printPath(){
ListIterator li = path.listIterator(path.size());
int lengthOfPath = (path.size()/2-1);
int fromX,fromY,bool = 0,toX = 0,toY = 0,i = 2;
while(li.hasPrevIoUs()){
if (bool == 0) {
fromX = (int) li.prevIoUs();
fromY = (int) li.prevIoUs();
toX = (int) li.prevIoUs();
toY = (int) li.prevIoUs();
System.out.println("From ("+fromY+","+fromX+") to ("+toY+","+toX+")");
booL++;
continue;
}
if (bool == 1){
fromX = toX;
fromY = toY;
toX = (int) li.prevIoUs();
toY = (int) li.prevIoUs();
System.out.println("From ("+fromY+","+toX+")");
i++;
}
}
System.out.println("\nLength of path is : "+lengthOfPath);
}
public static void main(String[] args){
int [][] maze = {{1,1,1},{1,9,1}};
MazeRunner p = new MazeRunner(maze);
p.runDFSAlgorithm(startingPoint[0],startingPoint[1]);
}
}
这是我用于测试的课程。它肯定适用于此示例,但不适用于更大的数组。 任何建议将不胜感激。当我在大型数组上运行程序时,出现以下错误:
解决方法
通常来说,只有两种可能性会导致stackoverflow异常 1.堆栈内存不足 2.存在一个死循环,在使用递归意味着不存在结束条件。
由于您一直在为小型迷宫工作。可能是原因之一。如您所知,递归规则是后进先出的,在JVM中,所有未执行函数的数据都将存储在堆栈中,堆栈的内存比堆小得多。
,除非确定可以将堆栈的深度限制为合理的数量,否则切勿在实际工作中使用递归算法。通常,这意味着最多O(log N)或O(log ^ 2 N)。
用于500x500迷宫的DFS可能会在堆栈上放置大约250000个函数调用,这太多了。
如果确实愿意,可以使用DFS,但应在单独的数据结构中维护自己的堆栈。不过,BFS会更好,除非出于某些原因您确实不想要最短的路径。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。