递归回溯解决迷宫问题
问题描述
现在有一个迷宫,要求我们从起点出发,走到出口位置,路线是什么样子的。
什么是回溯法
回溯法(探索与回溯法)是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的思想为回溯法。
如何使用回溯法的思想解决迷宫问题
通过上面对回溯法的解释,我们可以这么思考我们的迷宫问题。当我们从起点出发时,我们可以按照一个方向走开始寻找出路,当我们发现走不通了,就返回上一个位置(结点),然后换一个方向继续寻找出路,以此递推。。。。
使用编程语言描述问题
在这里我是用java 语言来表示问题,并解决。
首先 ,迷宫的创建可以是一个数组来创建,在此约定,数组中的元素,1表示迷宫的障碍,0则表示可以走的路。我们通过下面的代码来创建一个如图所示的迷宫。
public static void main(String[] args) {
// 初始化数组
int[][] map = new int[8][7];
// 外围一圈为墙 ,用1表示
for (int i = 0; i < 7; i++) {
map[0][i] = 1;
map[7][i] = 1;
}
for (int i = 1; i < 8; i++) {
map[i][0] = 1;
map[i][6] = 1;
}
// 设置迷宫 挡板,
map[3][1] = 1;
map[3][2] = 1;
map[2][2] = 1;
map[3][3] = 1;
map[2][3] = 1;
printMap(map);
}
解决思路
通过递归回溯法来遍历每一个位置的四个方向 ,直到能到达出口位置为止。
/**
* 走迷宫,需要走出迷宫的出路,使用递归,寻找通路
*
* <p>指定约定:
* <p>2表示该结点可以走,成功的路线,能走通就设置为2,1表示不能走,即障碍,迷宫的墙3 表示这个结点位置是死路,走不通
* <p>策略:
* <p>走到一个位置 按照 从下->右->上->左的方向探路,
*
* @param map 传入一个迷宫
* @param i 起点坐标
* @param j
* @return
*/
public static boolean setway(int[][] map, int i, int j) {
// 递归出口,当出口可以走通了,说明通路已经找到了
if (map[6][5] == 2) {
return true;
} else {
// 这个位置没有走过
if (map[i][j] == 0) {
// 将这个结点设置为走过,防止回来
map[i][j] = 2;
if (setway(map, i + 1, j)) {
return true;
} else if (setway(map, i, j + 1)) {
return true;
} else if (setway(map, i - 1, j)) {
return true;
} else if (setway(map, i, j - 1)) {
return true;
} else {
// 四个方向都走过了,不通这条路
map[i][j] = 3;
return false;
}
} else {
// 该结点不为0 已经走过了
return false;
}
}
}
通过迷宫问题,我们也能够发现递归的魅力所在,只需要很少的代码就能解决一个复杂的问题。在现实中,通过递归,回溯的方法能够解决的问题超级多。掌握回溯的思想并解决实际问题,需要我们不停的对递归思想进行思考,只有理解透彻了才能握住。