My problem is when i change the first parameter into over 300 in line 133, i get a java.lang.StackOverflowError in line 37.This line is a recursion. How can i solve this?
public class PathFindingOnSquaredGrid {
// given an N-by-N matrix of open cells, return an N-by-N matrix
// of cells reachable from the top
public static boolean[][] flow(boolean[][] open) {
int N = open.length;
boolean[][] full = new boolean[N][N];
for (int j = 0; j < N; j++) {
flow(open, full, 0, j);
}
return full;
}
// determine set of open/blocked cells using depth first search
public static void flow(boolean[][] open, boolean[][] full, int i, int j) {
int N = open.length;
// base cases
if (i < 0 || i >= N) return; // invalid row
if (j < 0 || j >= N) return; // invalid column
if (!open[i][j]) return; // not an open cell
if (full[i][j]) return; // already marked as open
full[i][j] = true;
flow(open, full, i+1, j); // down line 37
flow(open, full, i, j+1); // right line 38
flow(open, full, i, j-1); // left line 39
flow(open, full, i-1, j); // up line 40
}
// does the system percolate?
public static boolean percolates(boolean[][] open) {
int N = open.length;
boolean[][] full = flow(open);
for (int j = 0; j < N; j++) {
if (full[N-1][j]) return true;
}
return false;
}
//does the system percolate vertically in a direct way?
public static boolean percolatesDirect(boolean[][] open) {
int N = open.length;
boolean[][] full = flow(open);
int directPerc = 0;
for (int j = 0; j < N; j++) {
if (full[N-1][j]) {
// StdOut.println("Hello");
directPerc = 1;
int rowabove = N-2;
for (int i = rowabove; i >= 0; i--) {
if (full[i][j]) {
//StdOut.println("i: " + i + " j: " + j + " " + full[i][j]);
directPerc++;
}
else break;
}
}
}
// StdOut.println("Direct Percolation is: " + directPerc);
if (directPerc == N) return true;
else return false;
}
// draw the N-by-N boolean matrix to standard draw
public static void show(boolean[][] a, boolean which) {
int N = a.length;
StdDraw.setXscale(-1, N);;
StdDraw.setYscale(-1, N);
StdDraw.setPenColor(StdDraw.BLACK);
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
if (a[i][j] == which)
StdDraw.square(j, N-i-1, .5);
else StdDraw.filledSquare(j, N-i-1, .5);
}
// draw the N-by-N boolean matrix to standard draw, including the points A (x1, y1) and B (x2,y2) to be marked by a circle
public static void show(boolean[][] a, boolean which, int x1, int y1, int x2, int y2) {
int N = a.length;
StdDraw.setXscale(-1, N);;
StdDraw.setYscale(-1, N);
StdDraw.setPenColor(StdDraw.BLACK);
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
if (a[i][j] == which)
if ((i == x1 && j == y1) ||(i == x2 && j == y2)) {
StdDraw.circle(j, N-i-1, .5);
}
else StdDraw.square(j, N-i-1, .5);
else StdDraw.filledSquare(j, N-i-1, .5);
}
// return a random N-by-N boolean matrix, where each entry is
// true with probability p
public static boolean[][] random(int N, double p) {
boolean[][] a = new boolean[N][N];
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
a[i][j] = StdRandom.bernoulli(p);
return a;
}
// test client
public static void main(String[] args) {
ArrayList<Node> path=null;
Stopwatch timer;
// The following will generate a 10x10 squared grid with relatively few
obstacles in it
//The lower the second parameter, the more obstacles (black cells) are
generated
In here I was changing gird values to get test cases.
boolean[][] randomlyGenMatrix = random(350, 0.8); //line133
StdArrayIO.print(randomlyGenMatrix);
show(randomlyGenMatrix, true);
System.out.println();
//System.out.println("The system percolates: " + percolates(randomlyGenMatrix));
System.out.println();
//System.out.println("The system percolates directly: " + percolatesDirect(randomlyGenMatrix));
System.out.println();
Stopwatch timerFlow = new Stopwatch();
Scanner in = new Scanner(System.in);
System.out.println("Enter i for A > ");
int Ai = in.nextInt();
System.out.println("Enter j for A > ");
int Aj = in.nextInt();
System.out.println("Enter i for B > ");
int Bi = in.nextInt();
System.out.println("Enter j for B > ");
int Bj = in.nextInt();
// THIS IS AN EXAMPLE ONLY ON HOW TO USE THE JAVA INTERNAL WATCH
// Stop the clock ticking in order to capture the time being spent on inputting the coordinates
// You should position this command accordingly in order to perform the algorithmic analysis
StdOut.println("Elapsed time = " + timerFlow.elapsedTime());
//StdDraw.point(Ai, Bj);
// System.out.println("Coordinates for A: [" + Ai + "," + Aj + "]");
// System.out.println("Coordinates for B: [" + Bi + "," + Bj + "]");
show(randomlyGenMatrix, true, Ai, Aj, Bi, Bj);
String dis="";
while(!dis.equalsIgnoreCase("X")){
//Selecting the path
System.out.println("Enter Distance: (M)Manhattan|(E)Euclidean|(C)Chebyshev|(X)Exit");
dis=in.next();
timer=new Stopwatch();
path = new DijkstraAlgorithm(dis).distance(randomlyGenMatrix, Ai, Aj, Bi, Bj);
System.out.println("Elapsed time: "+timer.elapsedTime());
//Draw the path in the grid
for (Node node : path) {
StdDraw.filledCircle(node.y, 10 - node.x -1, .2);
}
}
System.exit(0);
}
}
The only thing you are using recursion for is to keep track of the locations that need to be checked. So you could instead have a queue of those locations, and keep processing the one popped off the head of the queue until the queue is empty. The body of the loop would look like the body of your flow
method (except the initial tests would continue
the loop instead of return
ing), but you would initialize the queue with the initial (i,j) location, and replace the recursive calls with enqueues of those locations.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.