java栈 迷宫_利用栈实现迷宫的求解
問題描述:這時實驗心理學中的一個典型的問題,心理學家吧一只老鼠從一個無頂?shù)拇蠛凶拥娜肟谔広s進迷宮。迷宮設置很多隔壁,對前進方向形成了許多障礙,心理學家在迷宮的唯一出口處放置了一塊奶酪,吸引老鼠仔迷宮中尋找通路以到達出口。
求解思想:回溯法是一種不斷試探且及時糾正錯誤的搜索方法,下面的求解過程采用回溯法。從入口出發(fā),按某一方向向前探索,若能走通(未走過的),即某處可以到達,則到達一個新點,否則試探下一個方向;若所有的方向均沒有通路,則沿原路返回前一點,換下一個方向繼續(xù)試探,直到所有可能的通路都搜索到,或找到一條通路,或無路可走又返回到入口點。這里可以用一個棧來實現(xiàn),每走一步,將該位置壓入棧中,若該點無路可走,則出棧返回上一位置。
需要解決的四個問題:
(1)表示迷宮的數(shù)據(jù)結構
設迷宮為m行n列,利用數(shù)組maze[m][n]來表示一個迷宮,maze[i][j]=0或1,其中0表示通路,1表示不通。迷宮該數(shù)組四邊都為1,代表迷宮四周都是墻。這樣就可以保證每個點都有8個方向可以試探。
入口為(1,1),出口為(6,8)
1,1,1,1,1,1,1,1,1,1
1,0,1,1,1,0,1,1,1,1
1,1,0,1,0,1,1,1,1,1
1,0,1,0,0,0,0,0,1,1
1,0,1,1,1,0,1,1,1,1
1,1,0,0,1,1,0,0,0,1
1,0,1,1,0,0,1,1,0,1
1,1,1,1,1,1,1,1,1,1
(2)試探方向
迷宮中間每個點都有8個方向可以試探。其增量數(shù)組可以用一個1*2的二維數(shù)組move表述,具體值如下:
x y
0 0 1
1??? 1?????1
2??? 1?????0
3??? 1???? -1
4??? 0?????-1
5??? -1??? -1
6??? -1?? ?0
7??? -1??? 1
在move數(shù)組中,x表示橫坐標的增量,y表示縱坐標的增量。
(3)棧中存放元素的設計
棧中所存放的元素應該包含所到達的每點的坐標以及從該點沿哪個方向向下走的。可以用一個類表示:
1 classStep{2 intx,y,d;3 public Step(int x,int y,intd) {4 this.x = x;//橫坐標
5 this.y = y;//縱坐標
6 this.d = d;//方向
7 }8 }
(4)防止重復到達某點而發(fā)生死循環(huán)
可以用兩種方法來實現(xiàn),第一種就是另外設置一個標志數(shù)組mark[m][n],它的所有元素初始都為0,一旦到達某點,則設置該點的標志位1,下次試探的時候就不再走這點了。第二種就是當?shù)竭_某點的時候,使maze[i][j]置為-1,以便區(qū)別為達到的點,同樣也可以防止走重復點的作用。
具體代碼如下:
1 packagecom.stack;2
3 importjava.util.Stack;4
5 /**
6 * 用棧來實現(xiàn)迷宮的求解7 *@author劉玲8 *9 */
10
11 classStep{12 intx,y,d;13 public Step(int x,int y,intd) {14 this.x = x;//橫坐標
15 this.y = y;//縱坐標
16 this.d = d;//方向
17 }18 }19
20 public classMazeTest {21
22 public static voidmain(String[] args) {23 //迷宮定義
24 int[][] maze = {{1,1,1,1,1,1,1,1,1,1},25 {1,0,1,1,1,0,1,1,1,1},26 {1,1,0,1,0,1,1,1,1,1},27 {1,0,1,0,0,0,0,0,1,1},28 {1,0,1,1,1,0,1,1,1,1},29 {1,1,0,0,1,1,0,0,0,1},30 {1,0,1,1,0,0,1,1,0,1},31 {1,1,1,1,1,1,1,1,1,1}};32 int[][] move = {{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1}};33 Stack s = new Stack();34 Stack s1 = new Stack();35 int a =path(maze, move, s);36 while(!s.isEmpty()){37 Step step =s.pop();38 System.out.println(step.x+":"+step.y);39 }40 }41 public static int path(int[][] maze,int[][] move,Stacks){42 Step temp = new Step(1,1,-1); //起點
43 s.push(temp);44 while(!s.isEmpty()){45 temp =s.pop();46 int x =temp.x;47 int y =temp.y;48 int d = temp.d+1;49 while(d<8){50 int i = x + move[d][0];51 int j = y + move[d][1];52 if(maze[i][j] == 0){ //該點可達
53 temp = new Step(i,j,d); //到達新點
54 s.push(temp);55 x =i;56 y =j;57 maze[x][y] = -1; //到達新點,標志已經(jīng)到達
58 if(x == 6 && y == 8){59 return 1; //到達出口,迷宮有路,返回1
60 }else{61 d = 0; //重新初始化方向
62 }63 }else{64 d++; //改變方向
65 }66 }67 }68 return 0;69 }70
71 }
輸出結果如下:
6:8
5:8
5:7
5:6
4:5
3:5
3:4
3:3
2:2
由于棧是后進先出的,所以結果應該從下面看起(2,2)->(3,3)->(3,4)->(3,5)->(4,5)->(5,6)->(5,7)->(5,8)->(6,8)
有運行結果可以看出來,棧中所存儲的就是迷宮的一條通路。
上面那個代碼有一點點小問題,非常感謝問題的提出者,修改如下:
1 packagecom.stack;2
3 importjava.util.Stack;4
5 /**
6 * 用棧來實現(xiàn)迷宮的求解7 *@author劉玲8 *9 */
10
11 classStep{12 intx,y,d;13 public Step(int x,int y,intd) {14 this.x = x;//橫坐標
15 this.y = y;//縱坐標
16 this.d = d;//方向
17 }18 }19
20 public classMazeTest {21
22 public static voidmain(String[] args) {23 //迷宮定義
24 int[][] maze = {{1,1,1,1,1,1,1,1,1,1},25 {1,0,1,1,1,0,1,1,1,1},26 {1,1,0,1,0,1,1,1,1,1},27 {1,0,1,0,0,0,0,0,1,1},28 {1,0,1,1,1,0,1,1,1,1},29 {1,1,0,0,1,1,0,0,0,1},30 {1,0,1,1,0,0,1,1,0,1},31 {1,1,1,1,1,1,1,1,1,1}};32 int[][] move = {{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},{-1,1}};33 Stack s = new Stack();34 int a =path(maze, move, s);35 while(!s.isEmpty()){36 Step step =s.pop();37 System.out.println(step.x+":"+step.y);38 }39 }40 public static int path(int[][] maze,int[][] move,Stacks){41 Step temp = new Step(1,1,-1); //起點
42 s.push(temp);43 while(!s.isEmpty()){44 //temp = s.pop(); 這樣寫是有問題的,不能將出棧的元素作為當前位置,應該將棧頂元素作為當前位置
45 s.pop(); //如果路走不通就出棧
46 if(!s.isEmpty()){47 temp = s.peek(); //將棧頂元素設置為當前位置
48 }49 int x =temp.x;50 int y =temp.y;51 int d = temp.d+1;52 while(d<8){53 int i = x + move[d][0];54 int j = y + move[d][1];55 if(maze[i][j] == 0){ //該點可達
56 temp = new Step(i,j,d); //到達新點
57 s.push(temp);58 x =i;59 y =j;60 maze[x][y] = -1; //到達新點,標志已經(jīng)到達
61 if(x == 6 && y == 1){62 return 1; //到達出口,迷宮有路,返回1
63 }else{64 d = 0; //重新初始化方向
65 }66 }else{67 d++; //改變方向
68 }69 }70 }71 return 0;72 }73
74 }
總結
以上是生活随笔為你收集整理的java栈 迷宫_利用栈实现迷宫的求解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java获取注解的属性值_反射+自定义注
- 下一篇: 元气骑士吊炸天怎么开启?