Java利用回溯思想解决迷宫问题(寻找最短路径)

迷宫存在数组里面,0代表路,1代表墙

为了保存已走过的数组下标,先创建一个ArrayXY类

public class ArrayXY {

	/**
	 * @param args
	 */
	public int x;
	public int y;
	
	ArrayXY(int x,int y){
		this.x = x;
		this.y = y;
	}
	
	public String toString(){
		return x + "," +y;
	}
	
	public boolean equals(Object o){//这个方法必须要记得重写,否则在主程序中没法判断是否包含
		if(o instanceof ArrayXY){
			ArrayXY oo = (ArrayXY)o;
			return this.x == oo.x && this.y == oo.y ? true: false;
		}else{
			return false;
		}
	}
}
然后写主函数,写在TestArray1这个类里面

当某个点周围有多条路可走的时候,算出每个可走点距离目标点的距离的平方,然后选择距离目标点最小的路径,当走入一个死胡同时,通过回溯,重新寻找路径,如果目标点不可达,就会输出“不可达”三个字。

好像原理跟A*算法有点像,启发函数就是目标点离可供选择路径的距离的平法,然后再加上回溯。如果说错了,还望批评指正。

自己用多个数组测试过,暂时是可行的。

import java.util.LinkedList;
import java.util.List;
import java.util.Stack;

public class TestArray1 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[][] testArray = { { 0, 1, 1, 0 ,1}, { 0, 0, 0, 1,1 }, { 0, 1, 0, 1, 1 },
				{ 1, 1, 0, 0, 1 },{0, 0, 0, 1, 1} };
		int startX = 0;
		int startY = 0;
		int targetX = 4;
		int targetY = 0;
		for(int i=0;i<testArray.length;i++){
			for(int j=0;j<testArray[0].length;j++)
				System.out.print(testArray[i][j]+" ");
			System.out.println();
		}
		TestArray1 ta = new TestArray1();
		// System.out.println(testArray[0].length);
		ta.searchLine(testArray, startX, startY, targetX, targetY);
	}

	public void searchLine(int[][] array, int startX, int startY, int targetX,
			int targetY) {
		if (array[startX][startY] == 1 || array[targetX][targetY] == 1)
			return;
		Stack<ArrayXY> xyStack = new Stack<ArrayXY>();
		List<ArrayXY> noPoint = new LinkedList<ArrayXY>();
		xyStack.push(new ArrayXY(startX,startY));
		while (startX < array.length && startY < array[0].length) {
			int uplength = -1;
			int downlength = -1;
			int leftlength = -1;
			int rightlength = -1;
			ArrayXY right = null;
			ArrayXY left = null;
			ArrayXY up = null;
			ArrayXY down = null;
			if (startY < array[0].length - 1)//右
				if (array[startX][startY + 1] == 0) {
					right = new ArrayXY(startX, startY+1);
					if (!noPoint.contains(right) && !xyStack.contains(right))//contains方法在底层调用了ArrayXY的equals方法,所以必须重写
						rightlength = (int) (Math.pow(targetX-startX,2)+Math.pow(targetY-startY-1, 2));
				}

			if (startX < array.length - 1)//下
				if (array[startX + 1][startY] == 0) {
					down = new ArrayXY(startX + 1, startY);
					if (!noPoint.contains(down) && !xyStack.contains(down))
						downlength = (int) (Math.pow(targetX-startX-1,2)+Math.pow(targetY-startY, 2));
				}
			
			if(startX > 0)//上
				if (array[startX - 1][startY] == 0) {
					up = new ArrayXY(startX - 1, startY);
					if (!noPoint.contains(up) && !xyStack.contains(up))
						uplength = (int) (Math.pow(targetX-startX+1,2)+Math.pow(targetY-startY, 2));
				}
			
			if(startY > 0)//左
				if (array[startX][startY -1] == 0) {
					left = new ArrayXY(startX, startY-1);
					if (!noPoint.contains(left) && !xyStack.contains(left))
						leftlength = (int) (Math.pow(targetX-startX,2)+Math.pow(targetY-startY+1, 2));
				}
			
			int minLength = -1;
			int flag = -1;
			if(uplength > 0){
				if((minLength > 0 && uplength <minLength)||minLength<0)
				{
					minLength = uplength;
					flag = 0;
				}
			}
			if(downlength > 0){
				if((minLength > 0 && downlength <minLength)||minLength<0)
				{	
					minLength = downlength;
					flag = 1;
				}
			}
			if(leftlength > 0){
				if((minLength > 0 && leftlength <minLength)||minLength<0)
				{
					minLength = leftlength;
					flag = 2;
				}
				
			}
			if(rightlength > 0){
				if((minLength > 0 && rightlength <minLength)||minLength<0)
				{
					minLength = rightlength;
					flag = 3;
				}
			}
			
			switch(flag){
			case 0://up
				startX--;
				xyStack.push(up);
				break;
			case 1://down
				startX++;
				xyStack.push(down);
				break;
			case 2://left
				startY--;
				xyStack.push(left);
				break;
			case 3://right
				startY++;
				xyStack.push(right);
				break;
			default:
				noPoint.add(xyStack.pop());
				if(xyStack.size() != 0){
					startX = xyStack.peek().x;
					startY = xyStack.peek().y;
				}
				break;
			}
				
			if(minLength == 1){
				xyStack.push(new ArrayXY(targetX,targetY));
				break;
			}
			
			if(xyStack.size() == 0){
				System.out.println("no way out");
				break;				
			}
			
		}
		
		
		System.out.println("一共"+xyStack.size()+"步");
		for(ArrayXY i: xyStack){
			System.out.print(i + "$");
		}

	}
}
运行结果如下:

0 1 1 0 1 
0 0 0 1 1 
0 1 0 1 1 
1 1 0 0 1 
0 0 0 1 1 
一共9步
0,0$1,0$1,1$1,2$2,2$3,2$4,2$4,1$4,0$


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值