2014-11-14 18 views
2

我正在嘗試使用DFS迷宮生成器生成大小爲350x350的迷宮。 我的代碼完美適用於大小爲150甚至250的矩陣,但如果我選擇upper,比如350x350,代碼將失敗並拋出stackOverflowErrors。 每當我嘗試撥打recursion(int x,int y)時遇到錯誤,有時我在Collection.shuffle(rn)處遇到錯誤。Java StackOverflowError - 生成一個相對較大的二維數組(350 x 350)

的主要方法是這一個:

Scanner console = new Scanner(System.in); 
int row = console.nextInt(); 
int column = console.nextInt(); 
Labirintus t = new Labirintus(row, column); 
t.generalLbairinuts(1, 1);  

。 這裏是創建迷宮類:

package projekt; 
import java.util.ArrayList; 
import java.util.Collections; 
public class Labirintus { 

private int row; 
private int column; 
private int [][] t; 

public Labirintus(int row, int column){ 
    this.row=row; 
    this.column=column; 
    t= new int[row][column]; 
    for(int i=0; i<row; ++i){ 
     for(int j=0; j<column; ++j){ 
      t[i][j]=1; 
     } 
    } 
} 

public int getRow(){ 
    return this.row; 
} 

public int getColumn(){ 
    return this.column; 
} 

public void setElement(Position p){ 
    t[p.getX()][p.getY()] = 0; 
} 

public void generalLbairinuts(int x, int y){ 

    recursion(x, y); 

} 

public int printXY(int x, int y){ 
    return this.t[x][y]; 
} 

public void recursion(int x, int y){ 

    Integer[] direction = randomDirection(); 

    for (int i=0; i< direction.length; ++i){ 
     switch(direction[i]){ 
      case 1: //Up 
       if(x<=2) continue; 
       if(this.t[x-2][y] != 0){ 
        this.t[x-2][y] = 0; 
        this.t[x-1][y] = 0; 
        recursion(x-2, y); 
       } 
       break; 
      case 2: //Right 
       if(y + 2 >= this.column - 1) continue; 
       if(this.t[x][y+2] != 0){ 
        this.t[x][y+2] = 0; 
        this.t[x][y+1] = 0; 
        recursion(x, y+2); 
       } 
       break; 
      case 3: //Down 
       if(x + 2 >= this.row - 1) continue; 
       if(this.t[x+2][y] != 0){ 
        this.t[x+2][y] = 0; 
        this.t[x+1][y] = 0; 
        recursion(x+2, y); 
       } 
       break; 
      case 4: //Left 
       if(y - 2 <= 0) continue; 
       if(this.t[x][y-2] != 0){ 
        this.t[x][y-2] = 0; 
        this.t[x][y-1] = 0; 
        recursion(x, y-2); 
       } 
       break; 
     } 
    } 

} 

public Integer[] randomDirection(){ 
    ArrayList<Integer> rn = new ArrayList<Integer>(); 
    for(int i=0; i<4; ++i){ 
     rn.add(i+1); 
    } 
    Collections.shuffle(rn); 
    return rn.toArray(new Integer[4]); 
} 
}  

位置級別是這樣的:

public class Position { 
private int x, y; 

public Position(int x, int y){ 
    this.x=x; 
    this.y=y; 
} 

public int getX(){ 
    return this.x; 
} 

public int getY(){ 
    return this.y; 
} 

public void setXY(int x, int y){ 
    this.x=x; 
    this.y=y; 
} 
}  

UPDATE1:

我在JAVA新的,所以我只認爲這是堆棧跟蹤:

Exception in thread "main" java.lang.StackOverflowError 
at java.util.Collections.shuffle(Collections.java:469) 
at projekt.Labirintus.randomDirection(Labirintus.java:105) 
at projekt.Labirintus.recursion(Labirintus.java:60) 
at projekt.Labirintus.recursion(Labirintus.java:77) 
at projekt.Labirintus.recursion(Labirintus.java:69) 
at projekt.Labirintus.recursion(Labirintus.java:77) 
at projekt.Labirintus.recursion(Labirintus.java:85) 
at projekt.Labirintus.recursion(Labirintus.java:77) 
at projekt.Labirintus.recursion(Labirintus.java:85) 
at projekt.Labirintus.recursion(Labirintus.java:85) 
at projekt.Labirintus.recursion(Labirintus.java:85) 
at projekt.Labirintus.recursion(Labirintus.java:77) 
at projekt.Labirintus.recursion(Labirintus.java:69) 
at projekt.Labirintus.recursion(Labirintus.java:77) 
at projekt.Labirintus.recursion(Labirintus.java:77) 
at projekt.Labirintus.recursion(Labirintus.java:77) 
at projekt.Labirintus.recursion(Labirintus.java:77) 
at projekt.Labirintus.recursion(Labirintus.java:77) 
at projekt.Labirintus.recursion(Labirintus.java:85) 
at projekt.Labirintus.recursion(Labirintus.java:85) 
... 
+1

你可以分配更多的內存到Java? – 2014-11-14 17:59:29

+2

你能給我們實際的堆棧跟蹤嗎? – forgivenson 2014-11-14 17:59:53

+0

另外檢查一些方法是否被稱爲其他方法,而其他方法是在內部調用第一個方法。 – 2014-11-14 18:16:56

回答

2

遞歸基本上一次又一次地調用相同的方法。所以你需要做的是使用一個標誌增加jvm允許的調用堆棧大小。這是而不是與增加程序內存相同。看到這個answer

+0

因此,如果我的理解是競爭性的,那就是說,當我使用一個大堆棧時,最好找到一個沒有像這個堆棧一樣使用堆棧的算法?或者在我的情況下,我需要顯着增加堆棧?準確地說是 – Norbert 2014-11-14 19:02:20

+0

。但是,如果這是你的堆棧的「限制」,那麼增加到這個限制就沒有問題。 – Abe 2014-11-14 19:02:56

+1

謝謝。然後我認爲我會將代碼轉錄爲迭代版本。 – Norbert 2014-11-14 19:48:48

0

你的問題引發了我的興趣,然後我開始用一個基於堆棧/隊列的迭代代碼做一個迷宮生成器來分叉你的代碼(這在SO帖子中提供),而不依賴於調用遞歸。 我完全改變了你的模型和算法,所以沒有任何原始的遺蹟。 我真的可以超過1000x1000的迷宮。 鑑於我的模型是基於移動而不是基於牆的,它對應於您的實現的2000x2000。 我用它來爲labrytinth創建一個stl生成器,以便能夠使用3D打印機進行打印。 它仍然沒有完成,但完整的代碼可以在這裏找到:https://github.com/artlog/labystl