Reputation: 1
Problem
Hello,
I'm doing Java project for my university studies and encountered a problem I could not solve myself, this is the first time I'm askin a question here so tell me if I did anything wrong.
I am trying to solve a simply connected maze using a Wall follower algorithm, the algorithm walks the maze and always trys to turn right then move forward and lastly turns right. Whe encountering a dead the algorithm it will turn around and start moving back.
My recursive soution causes a StackOverflow error when the maze size is above 500 x 500. I am wondering is there a error in the code or is it just not viable to solve this kind of problem with recursive algorithm.
NOTE: The problem is not that the algorithm does not work but that it runs out of Stack!
** Question **
Is there a loop or memory leak or is it just not possible to use recursion after a certain number of calls.
I have a iterative solution that works at any maze size.
Program
the Maze is represented as a 2D-array and each square has its own class that holds it coordinates inside the maze. My thinking is that Java stores these Square objects without cleaning them while the recursive method is running. The move() method calls a method getSquareInDirection that creates a new Square object, that might cause the error. The other methods only alter the enum Dircetion and should not be the cause of the error, but I am not sure of this.
Parent method
public SquareQue solveRecursive() {
Square start = maze.getStart();
SquareQue path = new SquareQue();
move(start, Direction.DOWN, path);
maze.setSquareValue(start.getWidth(), start.getHeight(), 3);
return path;
}
Recursive method
public SquareQue move(Square pos, Direction dir, SquareQue path) {
if (maze.reachedFinish(pos)) {
path.add(pos);
return path;
}
if (canMove(pos, getDirectionToRight(dir))) {
pos = getSquareInDirection(pos, getDirectionToRight(dir));
path.add(pos);
return move(pos, getDirectionToRight(dir), path);
} else if (canMove(pos, dir)) {
pos = getSquareInDirection(pos, dir);
path.add(pos);
return move(pos, dir, path);
} else if (canMove(pos, getDirectionToLeft(dir))) {
pos = getSquareInDirection(pos, getDirectionToLeft(dir));
path.add(pos);
return move(pos, getDirectionToLeft(dir), path);
} else {
pos = getSquareInDirection(pos, reverse(dir));
return move(pos, reverse(dir), path);
}
}
Recrsuvie method calls this
public static Square getSquareInDirection(Square pos, Direction dir) {
int col = pos.getWidth();
int row = pos.getHeight();
if (dir == Direction.UP) {
return new Square(col, row - 1);
}
if (dir == Direction.DOWN) {
return new Square(col, row + 1);
}
if (dir == Direction.RIGHT) {
return new Square(col + 1, row);
}
if (dir == Direction.LEFT) {
return new Square(col - 1, row);
}
return null;
}
Reproduce error
Easiest way to reproduce the error is to clone the project and edit the GUI class.
Inside GUI class inside the method getSolveScene and alter the button settings for calling a large recursive result method:
if (selectedString.equals("Large")) {
stage.setScene(getSolveScene(81, 81, 12, setting));
stage.setTitle("Maze generator - Recursive Large");
}
Repalce the getSolveScene with for example: (getSolveScene(501, 501, 12, setting)
.
After this you can save and run the progra with settings Large and Recursive.
Thanks in advance for responding!
Upvotes: 0
Views: 381
Reputation: 10151
The default stack size is quite small (at least often too small for recursive algorithms). Default is in most VMs only 1MByte.
To change the stack size use the VM-parameter: -Xss
But to check if the stack size is your only problem, try to solve a smaller maze first.
Upvotes: 0
Reputation: 4667
Recursive approach should work as long as your stack size is large enough to accomodate the required depth of recursion (that depends on the size of your maze).
However, I also see another problem - getSquareInDirection
doesn't seem to be checking not to go back to the path that was already visited. If that happens, your program might get stuck in a "loop" a.k.a. infinite recursion. Try printing current coordinates in move
and see if they repeat themselves. (Hint: they should not)
Upvotes: 1