老鼠走迷宫问题

参考http://caterpillar.onlyfun.net/Gossip/AlgorithmGossip/MouseGoMaze.htm

问题有一个迷宫,在迷宫的某个出口放着一块奶酪。将一只老鼠由某个入口处放进去,它必须穿过迷宫,找到奶酪。请找出它的行走路径。

解法:这个问题可以用递归的方法去求解。

        先来看下面这幅图:

《老鼠走迷宫问题》

        绿色箭头指向的是迷宫的入口,将小老鼠由此放入,红色箭头的位置就是奶酪的所在地,小老鼠必须穿过迷宫从红色箭头标示的地方走出去。

我们用一个二维数组来表示迷宫,用2表示迷宫的墙壁,即上图中的黑色部分,用0表示通路,即上图中老鼠可以行走空白的格子。老鼠每走到一个格子的时候就将该位置的值置为1,表示老鼠的行走路径包括这个格子。

        接下来说一下老鼠的行走策略:老鼠每走一步(格子)的时候,将该格子的值置为1,然后会依次考察该格子的右、下、左、上位置的格子是否可走(可走的标志是该格子的值为0)。这样老鼠从入口的格子出发,就会派生出很多可能的行走路径,如果某一条路不能走到终点的话,那么就要将相应的格子的值重新置为0了,表示正确的路径不包括这个格子。

        好了,终于到具体的实现代码了:

public class Mouse {

	public static void main(String[] args) {
		
		int[][] maze={{2,2,2,0,2,2,2,0,0},
				      {2,0,0,0,0,0,2,0,0},
				      {2,0,2,2,2,2,2,2,2},
				      {0,0,0,0,0,0,0,0,2},
				      {2,0,2,2,2,2,0,2,2},
				      {2,0,2,2,0,0,0,2,2},
				      {2,0,2,2,0,2,2,0,2},
				      {2,0,2,0,0,0,0,0,0},
				      {2,0,2,2,2,2,2,2,2}		
		             };
		Map map=new Map(maze, new Point(7, 8));
		Mouse.go(map, new Point(0,3));
		map.print();
	
	}
	public static void go(Map map,Point p){
		
		   map.step(p);
		   if(p.y<map.maze[0].length-1)
		   {
			   test(map,new Point(p.x, p.y+1));
		   }
		   if(p.x<map.maze.length-1)
		   {
			   test(map,new Point(p.x+1, p.y));
		   }
		   if(p.y>=1)
		   {
			   test(map,new Point(p.x, p.y-1));
		   }
		   if(p.x>=1)
		   {
			   test(map,new Point(p.x-1, p.y));
		   }
		   if(!map.isArrived())
			   map.empty(p);
	}
   public static void test(Map map,Point p){
		
		if(!map.isArrived() && map.isEmpty(p)){
			go(map,p);
		}
	}		
}

class Point{
	
	int x;
	int y;
	public Point(int x1,int y1){
		
		x=x1;
		y=y1;
	}
}
class Map{
	
	int[][] maze;
	Point end;    //终点
	public Map(int[][] maze,Point end){
		
		this.maze=maze;
		this.end=end;
		
	}
	//是否到达终点
	public boolean isArrived(){
		
		return maze[end.x][end.y]==1;
		
	}
	//当前这一格是否可行
	public boolean isEmpty(Point p){
		
		  return maze[p.x][p.y]==0;
	}
	//可以理解为当经过Point p 无法走到终点时,把老鼠走过的痕迹抹去,表示最终的走法不含p
	public void empty(Point p){
		
		maze[p.x][p.y]=0;
		
	}
	//走到Point p
	public void step(Point p){
		
			maze[p.x][p.y]=1;
		
	}
	//打印地图,含老鼠走过的路径
	public void print(){
		for(int i=0;i<maze.length;i++)
		 {
			for(int j=0;j<maze[0].length;j++)
			    if(maze[i][j]==2){
			    	 System.out.print("█");
			    }else if(maze[i][j]==0){
			    	System.out.print(" ");
			    }else if(maze[i][j]==1){
			    	System.out.print("1");
			    }
			System.out.println();	
		 }
		
	}
    	
}

       运行结果如下:

《老鼠走迷宫问题》

可见,小老鼠成功地走到了终点。

        如果迷宫的设计使得走法不止一种,则只要在老鼠走至出口时显示出所有的路径,然后退回上一格重新选择下一个位置继续递归就可以了。如下图有两种走法。

《老鼠走迷宫问题》

代码作了一点点儿修改:

public class Mouse {

	public static void main(String[] args) {
		
		int[][] maze={{2,2,2,0,2,2,2,0,0},
				      {2,0,0,0,0,0,2,0,0},
				      {2,0,2,2,2,0,2,2,2},
				      {0,0,0,0,0,0,0,0,2},
				      {2,0,2,2,2,2,0,2,2},
				      {2,0,2,2,0,0,0,2,2},
				      {2,0,2,2,0,2,2,0,2},
				      {2,0,2,0,0,0,0,0,0},
				      {2,0,2,2,2,2,2,2,2}		
		             };
		Map map=new Map(maze, new Point(7, 8));
		Mouse.go(map, new Point(0,3));
		//map.print();
	
	}
	public static void go(Map map,Point p){
		
		   map.step(p);
		   if(map.isArrived())
		   {
			   map.print();
			   map.maze[map.end.x][map.end.y]=0;
		   }
			   
		   if(p.y<map.maze[0].length-1)
		   {
			   test(map,new Point(p.x, p.y+1));
		   }
		   if(p.x<map.maze.length-1)
		   {
			   test(map,new Point(p.x+1, p.y));
		   }
		   if(p.y>=1)
		   {
			   test(map,new Point(p.x, p.y-1));
		   }
		   if(p.x>=1)
		   {
			   test(map,new Point(p.x-1, p.y));
		   }
		   
			   map.empty(p);
	}
   public static void test(Map map,Point p){
		
		if(!map.isArrived() && map.isEmpty(p)){
			go(map,p);
		}
	}		
}

class Point{
	
	int x;
	int y;
	public Point(int x1,int y1){
		
		x=x1;
		y=y1;
	}
}
class Map{
	
	int[][] maze;
	Point end;    //终点
	public Map(int[][] maze,Point end){
		
		this.maze=maze;
		this.end=end;
		
	}
	//是否到达终点
	public boolean isArrived(){
		
		return maze[end.x][end.y]==1;
		
	}
	//当前这一格是否可行
	public boolean isEmpty(Point p){
		
		  return maze[p.x][p.y]==0;
	}
	//可以理解为当经过Point p 无法走到终点时,把老鼠走过的痕迹抹去,表示最终的走法不含p
	public void empty(Point p){
		
		maze[p.x][p.y]=0;
		
	}
	//走到Point p
	public void step(Point p){
		
			maze[p.x][p.y]=1;
		
	}
	//打印地图,含老鼠走过的路径
	public void print(){
		for(int i=0;i<maze.length;i++)
		 {
			for(int j=0;j<maze[0].length;j++)
			    if(maze[i][j]==2){
			    	 System.out.print("█");
			    }else if(maze[i][j]==0){
			    	System.out.print(" ");
			    }else if(maze[i][j]==1){
			    	System.out.print("1");
			    }
			System.out.println();	
		 }
		System.out.println();
	}
    	
}

运行结果:

《老鼠走迷宫问题》

~完~

    原文作者:迷宫问题
    原文地址: https://blog.csdn.net/zhutulang/article/details/7539692
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞