一个求迷宫入口到出口最近距离的程序 JAVA版本

139 篇文章 2 订阅


本文给出一个JAVA 语言版的求迷宫入口到出口的最短路径的程序。程序的大部分使用标准c语言编写,包括
输入和输出。唯一用到C++库的地方是使用STL了中的deque。迷宫的宽和高,迷宫矩阵,迷宫的入口和出口
等数据从文件读入。程序首先读入迷宫数据,然后更新迷宫矩阵,并求出迷宫入口和出口之间的最短路径,
并输出最短路径长度。

C++版本的在这里: http://blog.csdn.net/liangbch/article/details/7595177


开始时,迷宫矩阵的每一个元素是0或-1,0表示可走,-1表示是墙,走不通。对所有和迷宫入
口相通的方格,其值被改为其距迷宫入口的最近距离(比如:5*5的矩阵)

{ 0,  0,  0,  0,  0},    
{-1,  0, -1,  0, -1},    
{ 0,  0, -1, -1, -1},    
{ 0, -1,  0,  0,  0},    
{ 0,  0,  0, -1,  0},


2.算法

  迷宫的矩阵的每一方格可用 MazeNode表示,里面最重要的是三个数字(x,y,d)来表示,x,y表示这个方格的坐标,d表示这个方格距入口
的距离.

  1.首先,将入口的坐标(x,y,0),放入双端队列my_queue。
  2. 接下来重复以下的过程,直到队列为空:

    2.1.从队列头部取出一个MazeNode,三元组(x,y,d)
    2.2.从右,下,左,上四个方向搜索找最相邻的一个节点, :

       如果是 -1的格子(就是墙),则跳过;如果这个方格不是入口点,则有3种情况
      case 1.
      新方格对应的矩阵元素是0,表明新的方格距迷宫入口的距离尚未标记。
   则将新方格对应的矩阵元素设置为d+1,同时将三元组(x,y,d+1)入队
      case 2:
      新方格的对应的矩阵元素的值>d+1,表明该新方格距迷宫入口的距离已经标记但不是最近的。
   则将新方格对应的矩阵元素设置为d+1,同时将三元组(x,y,d+1)入队  
     case 3:
     如果新的方格的对应的矩阵元素<= d+1,该位置距入口的距离已经标记,则不做处理

  3.检查出口对应的矩阵元素M[exit.x][exit.y]的值,如果为0,表示没有一条路径可走,否则打印出
    口距入口的距离。

全部的代码见下:

package algorithm;
import java.util.*;
public class MazeShow {
     public static class MazeNode {	
	/* 0 means it is not processed yet or it is entrance point
	 * >0 means the shortest distance from the entrance node  
	 */
	private int distance; 
	/*
	 * data: it is setup during initialization phase.
	 * -1: means this node is wall.
	 * 0: means it can be went through.
	 */
	private int data;
	private int row;
	private int column;
	boolean isStartPoint;
	boolean isExitPoint;
	
	public MazeNode(){
		distance=0;
		data=0;
		column=0;
		row=0;
		isStartPoint=false;
		isExitPoint=false;
	}
	public int getRow(){
		return row;
	}
	public int getColumn(){
		return column;
	}
	public void setRow(int row){
		this.row=row;
	}
	public void setColumn(int column){
		this.column=column;
	}
	public int getDistance(){
		return distance;
	}
	public void setData(int data){
		this.data=data;
	}	
	public void setDistance(int dis){
		distance=dis;
	}
	public int getData(){
		return data;
	}	
	public void setStartPoint(boolean value){
		isStartPoint=value;
	}
	public void setEndPoint(boolean value){
		isExitPoint=value;
	}
	public boolean getStartPoint(){
		return isStartPoint;
	}
	public boolean getEndPoint(){
		return isExitPoint;
	}
   }
    
	public static int getMazeShortestDistance(){	
	   int MAZE_WIDTH=5;
	    int MAZE_HEIGHT=5;
	    int distance=0;
	    MazeShow.MazeNode[][] mymaze=new MazeShow.MazeNode[MAZE_HEIGHT][MAZE_WIDTH];
	    for(int height=0;height<MAZE_HEIGHT;height++)
	      for(int width=0;width<MAZE_WIDTH;width++) {
	    	  //Java OBJ array must create new each obj element after TYPE[][] m=new TYPE[5]6];
	    	  mymaze[height][width]=new MazeShow.MazeNode();
	    	  mymaze[height][width].setRow(height);
	    	  mymaze[height][width].setColumn(width);
	      }
	    
	    //set up as(0,0) as entrance point 
	    
	    mymaze[0][0].setData(0);
	    mymaze[0][0].setDistance(0);
		
	    //set up as(MAZE_WIDTH-1,MAZE_HEIGHT-1) as exit point 
		
	    mymaze[MAZE_HEIGHT-1][MAZE_WIDTH-1].setData(0);
	    mymaze[MAZE_HEIGHT-1][MAZE_WIDTH-1].setDistance(0);
	    
	    //set maze as below which is wall
	    /*
	     *   
       { 0,  0,  0,  0,  0},    
       {-1,  0, -1,  0, -1},    
       { 0,  0, -1, -1, -1},    
       { 0, -1,  0,  0,  0},    
       { 0,  0,  0, -1,  0},
	     * 
	     */
	    mymaze[1][0].setData(-1);
	    
	    mymaze[3][1].setData(-1);
	    
	    mymaze[1][2].setData(-1);
	    mymaze[2][2].setData(-1);
	    
	    mymaze[2][3].setData(-1);
	    mymaze[4][3].setData(-1);
	    
	    mymaze[1][4].setData(-1);
	    mymaze[2][4].setData(-1);
	    
	    //process now
	    Queue<MazeShow.MazeNode> mazequeue = new LinkedList<MazeShow.MazeNode>();
	    
	    //push the entrance point as start point
	    
	    mazequeue.offer(mymaze[0][0]);
	    MazeShow.MazeNode pnode=null;
	    
	    int pcolumn=0;
		int prow=0;
		MazeShow.MazeNode currentNode=null;
		
	    while(!mazequeue.isEmpty()) {
	    	//get the FIFO node from queue;
	    	currentNode=null;
	    	pnode=mazequeue.poll();
	    	
	    	for(int turn=0;turn<4;turn++) {
	    	 switch(turn) {
	    	  case 0: //left
	    		  if(pnode.getColumn()>0) {
	    			 pcolumn=pnode.getColumn()-1;
	 	    		 prow=pnode.getRow();
	 	    		 currentNode=mymaze[prow][pcolumn];
	    		   }
	    		  else 
	    			  currentNode=null;  
	    		    break;
	    	 case 1: //down	    		 
	 	    	  if(pnode.getRow()<(MAZE_HEIGHT-1)) {
	 	    		// not the lowest node
	 	    		pcolumn=pnode.getColumn();
		 	    	prow=pnode.getRow()+1;
		 	    	currentNode=mymaze[prow][pcolumn];
	 	    	  }
	 	    	  else 
	    			  currentNode=null;  
	    		    break;
	    	 case 2: //right 
	 	    	 if(pnode.getColumn()<(MAZE_WIDTH-1)) {
	 	    		// not the most right node
	 	    		 pcolumn=pnode.getColumn()+1;
	 	    		 prow=pnode.getRow();
	 	    		 currentNode=mymaze[prow][pcolumn];
	 	    	  }
	 	    	 else 
	    			  currentNode=null;  
	    		   break;
	    	 case 3: //up
	 	    	  if(pnode.getRow()>0) {
	 	    		 pcolumn=pnode.getColumn();
	 	    		 prow=pnode.getRow()-1;
	 	    		 currentNode=mymaze[prow][pcolumn];
	 	    	  } else
	 	    		 currentNode=null;  
	    		    break;
	    		    
	    	 default:
	    		   System.out.println("error, shall not reach here");
	    		   return -1;
	    	 }	
	    	 
	    	 if(currentNode==null)
	    		 continue;
	    	 //skip the wall node
	    	  if(currentNode.getData()== -1)
	    		 continue;
	    	
	    	  distance=currentNode.getDistance();
	    	  if(distance==0 && (!currentNode.getStartPoint())){
	    			  //this is node not processed yet and it is not startpoint
	    		   currentNode.setDistance(pnode.getDistance()+1);
	    		   mazequeue.offer(currentNode);
	    	  } 
	    	  else { if(distance>(pnode.getDistance()+1)){
	    				  //update to make it shorted
	    			 currentNode.setDistance(pnode.getDistance()+1);
	  	    		 mazequeue.offer(currentNode);
	    		     } 
	    	        else { //if distance < (pnode.getDistance()+1
	    		    	    //nothing to do	    		    	 
	    		     }	    			  
	    		  }	    			  
	    		}
	    	}
	    
		return (distance= mymaze[MAZE_HEIGHT-1][MAZE_WIDTH-1].getDistance());
	}
}


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值