从拼图游戏开始(二)_带优先搜索的地图路线搜索java实现

       昨晚想着到目前为止这个拼图游戏的算法求解还是没有思路,想着先写一个简单的地图路线搜索来体会一下也许能找到一点感觉,于是就有了本文。这里的搜索考虑了从起点到终点的优先搜索(即以起点和终点的坐标差为依据,每一次搜索都以靠近终点的方向为优先搜索方向,当所有能够更加靠近终点的方向都不通时,才尝试搜索远离终点的方向)。这里的搜索是基于深搜的,所以路径是用栈来保存的,代码如下:

package com.wly.algorithmbase.search;

/**
 * 简单的地图路线深搜遍历
 * 
 * @author wly
 * 
 */
public class MapSearch {
	
	//0:自身 1:通路  2:石头 3:目标
	private static int[][] graph1 = { //包含通路实例
		{ 3, 1, 1, 1},
		{ 1, 2, 1, 2},
		{ 1, 2, 2, 1},
		{ 1, 1, 2, 1},
		{ 2, 1, 0, 1},
		{ 2, 2, 2, 1}
	};

	private static int[][] graph2 = { //不包含通路实例
		{ 3, 2, 1, 1},
		{ 2, 1, 1, 2},
		{ 1, 1, 2, 1},
		{ 1, 2, 2, 1},
		{ 1, 1, 0, 1},
	    { 2, 2, 2, 1}
	};

	private static int[][] graph3 = { //包含通路实例
		{ 3, 2, 1, 2 }, 
		{ 1, 2, 1, 1 },
		{ 1, 2, 2, 1 }, 
		{ 1, 1, 1, 1 }, 
		{ 1, 1, 2, 1 }, 
		{ 2, 2, 2, 0 } 
	};

	private static boolean[][] isVisited;
	// 自身坐标
	static int dest_row, dest_column;
	// 目标坐标
	static int self_row, self_column;
	
	//将起点放入到检索结果路径栈中去
	static MyStack stack = new MyStack();

	public static void main(String[] args) {
		MapSearch mapSearch = new MapSearch();
		mapSearch.search(graph1);
		mapSearch.search(graph2);
		mapSearch.search(graph3);
	}
	
	public void search(int[][]graph) {
		
		//打印地图结构
		System.out.println("--地图----");
		for(int[] i:graph) {
			for(int j:i) {
				System.out.print(j + " ");
			}
			System.out.println();
		}
			
		//将访问标记初始化成false,即都未访问过
		isVisited = new boolean[graph.length][graph[0].length];
		for (int i = 0; i < graph.length; i++) {
			for (int j = 0; j < graph[0].length; j++) {
				isVisited[i][j] = false;
			}
		}

		//根据地图数据,得到出发坐标和目标坐标
		for (int i = 0; i < graph.length; i++) {
			for (int j = 0; j < graph[0].length; j++) {
				if (graph[i][j] == 0) {
					self_row = i;
					self_column = j;
				} else if (graph[i][j] == 3) {
					dest_row = i;
					dest_column = j;
				}
			}
		}

		//起点与终点的坐标差,用于控制搜索方向
		int delta_x = self_column - dest_column;
		int delta_y = self_row - dest_row;


		Point startP = new Point(self_row, self_column);
		isVisited[self_row][self_column] = true;
		stack.push(startP);

		// 搜索到结果,或未搜索到结果
		while ((delta_x != 0 || delta_y != 0) && !stack.isEmpty()) { 
			Point pTop = stack.peek();
			if (pTop == null) {
				break;
			}
			//对靠近终点的方向进行优先搜索
			if (pTop.row > 0 && pTop.row < graph.length - 1
					&& pTop.column > 0 
					&& pTop.column < graph[0].length - 1) {
				if (delta_x > 0) { // 向左搜索
					if (graph[pTop.row][pTop.column-1] != 2
							&& isVisited[pTop.row][pTop.column-1] == false)
					{
						Point p = new Point(pTop.row, pTop.column - 1);
						isVisited[pTop.row][pTop.column - 1] = true;
						stack.push(p);
						delta_x--;
						continue;
					}
				} else if (delta_x < 0) { // 向右搜索
					if (graph[pTop.row][pTop.column + 1] != 2
							&& isVisited[pTop.row][pTop.column+1] == false)
					{
						Point p = new Point(pTop.row, pTop.column + 1);
						isVisited[pTop.row][pTop.column + 1] = true;
						stack.push(p);
						delta_x++;
						continue;
					}
				}

				if (delta_y > 0) { // 向上搜索
					if (graph[pTop.row - 1][pTop.column] != 2
							&& isVisited[pTop.row-1][pTop.column] == false)
					{
						Point p = new Point(pTop.row - 1, pTop.column);
						isVisited[pTop.row - 1][pTop.column] = true;
						stack.push(p);
						delta_y--;
						continue;
					}
				} else if (delta_y < 0) { // 向下搜索
					if (graph[pTop.row + 1][pTop.column] != 2
							&& isVisited[pTop.row+1][pTop.column] == false)
					{
						Point p = new Point(pTop.row + 1, pTop.column);
						isVisited[pTop.row + 1][pTop.column] = true;
						stack.push(p);
						delta_y++;
						continue;
					}
				}
			}
			
			//优先方向搜索失败(如遇到石头)后,进行周边其他方向的搜索
			if (pTop.column > 0 && graph[pTop.row][pTop.column - 1] != 2
					&& isVisited[pTop.row][pTop.column-1] == false) {
				Point p = new Point(pTop.row, pTop.column - 1);
				isVisited[pTop.row][pTop.column - 1] = true;
				stack.push(p);
				delta_x--;
				continue;
			} else if (pTop.column < graph[0].length-1
					&& graph[pTop.row][pTop.column + 1] != 2
					&& isVisited[pTop.row][pTop.column+1] == false) {
				Point p = new Point(pTop.row, pTop.column + 1);
				isVisited[pTop.row][pTop.column + 1] = true;
				stack.push(p);
				delta_x++;
				continue;
			}
			if (pTop.row > 0 && graph[pTop.row - 1][pTop.column] != 2
					&& isVisited[pTop.row-1][pTop.column] == false) {
				Point p = new Point(pTop.row - 1, pTop.column);
				isVisited[pTop.row - 1][pTop.column] = true;
				stack.push(p);
				delta_y--;
				continue;
			} else if (pTop.row < graph.length-1
					&& graph[pTop.row + 1][pTop.column] != 2
					&& isVisited[pTop.row+1][pTop.column] == false) {
				Point p = new Point(pTop.row + 1, pTop.column);
				isVisited[pTop.row + 1][pTop.column] = true;
				stack.push(p);
				delta_y++;
				continue;
			}
			//未搜索有效的节点,弹出当前节点(回溯操作)
			stack.pop();

		}
		
		//打印最终搜索路径
		Point p = stack.pop();
		if(p == null) {
			System.out.println("未找到从起点(" + self_row 
					+ "," + self_column + ")到终点(" + dest_row 
					+ "," + dest_column + ")的有效路径\n");
		} else {
			System.out.print("终点");
			while(p != null) {
				System.out.print("(" + p.row + "," 
						+ p.column + ")" + "<=");
				p = stack.pop();
			}
			System.out.print("起点\n\n");
		}
	}
}

/**
 * 用于在深搜中保存路径的栈结构
 * @author wly
 *
 */
class MyStack {

	Point[] array;
	private int CAPACITY = 12;
	private int mTop = -1;

	public MyStack() {
		array = new Point[CAPACITY];
	}

	public void push(Point p) {
		if (mTop == array.length) { // 扩展容量
			Point[] temp = new Point[array.length + CAPACITY];
			for (int i = 0; i < array.length; i++) {
				temp[i] = array[i];
			}
		}
		mTop = mTop + 1;
		array[mTop] = p;
	}

	public Point pop() {
		if(mTop >= 0) {
			Point p = new Point(array[mTop]);
			array[mTop--] = null;
			return p;
		} else {
			return null;
		}
	}

	public Point peek() {
		if (mTop >= 0) {
			return array[mTop];
		} else {
			return null;
		}
	}

	public boolean isEmpty() {
		return mTop < 0;
	}
}

/**
 * 地图中的点
 * @author wly
 *
 */
class Point {
	public int row, column;

	public Point(Point p) {
		this.row = p.row;
		this.column = p.column;
	}

	public Point(int row, int column) {
		this.row = row;
		this.column = column;
	}
}

      运行结果:

--地图----
3 1 1 1 
1 2 1 2 
1 2 2 1 
1 1 2 1 
2 1 0 1 
2 2 2 1 
终点(0,0)<=(1,0)<=(2,0)<=(3,0)<=(3,1)<=(4,1)<=(4,2)<=起点

--地图----
3 2 1 1 
2 1 1 2 
1 1 2 1 
1 2 2 1 
1 1 0 1 
2 2 2 1 
未找到从起点(4,2)到终点(0,0)的有效路径

--地图----
3 2 1 2 
1 2 1 1 
1 2 2 1 
1 1 1 1 
1 1 2 1 
2 2 2 0 
终点(0,0)<=(1,0)<=(2,0)<=(3,0)<=(3,1)<=(3,2)<=(3,3)<=(4,3)<=(5,3)<=起点
      O啦~~~

      转载请保留出处:http://blog.csdn.net/u011638883/article/details/17238855

      谢谢!!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值