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