回溯算法经典应用之—迷宫问题 (Java)
来源:互联网 发布:golang 连接mongodb 编辑:程序博客网 时间:2024/05/21 09:31
1、回溯算法简介
回溯算法也叫试探法,它是一种系统地搜索问题的解的方法。回溯算法的基本思想是:从一条路往前走,能进则进,不能进则退回来,换一条路再试。用回溯算法解决问题的一般步骤为:
1)、定义一个解空间,它包含问题的解。
2)、利用适于搜索的方法组织解空间。
3)、利用深度优先法搜索解空间。
4)、利用限界函数避免移动到不可能产生解的子空间。
返回值为true;
回溯算法也叫试探法,它是一种系统地搜索问题的解的方法。回溯算法的基本思想是:从一条路往前走,能进则进,不能进则退回来,换一条路再试。用回溯算法解决问题的一般步骤为:
1)、定义一个解空间,它包含问题的解。
2)、利用适于搜索的方法组织解空间。
3)、利用深度优先法搜索解空间。
4)、利用限界函数避免移动到不可能产生解的子空间。
问题的解空间通常是在搜索问题的解的过程中动态产生的,这是回溯算法的一个重要特性。
2、问题定义
问题:给定一个迷宫,找到从入口到出口的所有可行路径。如下图所示:
思路:
由于路径不能重复进入矩阵的格子,还需要定义和字符矩阵大小一样的布尔值矩阵,用来标识路径是否已经进入每个格子。 当矩阵中坐标为(row,col)的格子和路径字符串中相应的字符一样时,从4个相邻的格子(row,col-1),(row-1,col),(row,col+1)以及(row+1,col)中去定位路径字符串中下一个字符如果4个相邻的格子都走不通时,表明当前路径不正确,我们需要回到前一个,然后重新规划路线。一直重复这个过程,直到找到终点。
解题步骤:
1)、从起点开始,逐步向其它路径四周扩展路径。
2)、每走一步判断,如果未到达继续四周扩展路径。
3)、记录下路径,如果走到思路则回退到上一步。
先贴上第一个版本的代码,次代码只能返回是否有路径,比较简单一点:
package com.qian.backtracing;public class Maze {public boolean hasPath(boolean[][] road, int sRow, int sCol, int tRow, int tCol) {boolean[][] hasVisited = new boolean[road.length][road[0].length];if(!road[sRow][sCol] || !road[tRow][tCol]) return false;for (int i = 0; i < road.length; i++) {for (int j = 0; j < road[0].length; j++) {if(road[i][j])System.out.print("√,");elseSystem.out.print("x,");}System.out.println();}boolean rst = hasPathCore(road, sRow, sCol, tRow, tCol, hasVisited);return rst;}/** * 回溯递归函数 * @param road 路线图 * @param row行号 * @param col列号 * @param tRow终点行号 * @param tCol终点列号 * @param hasVisited是否被访问数组 * @return */public boolean hasPathCore(boolean[][] road, int row, int col, int tRow, int tCol,boolean[][] hasVisited) {int cols = road[0].length;int rows = road.length;//System.out.println(cols + ";;" + rows );if (col < 0|| col >= cols|| row < 0|| row >= rows|| !road[row][col] //路是通的|| hasVisited[row][col])return false;if (row == tRow && col == tCol) //递归函数的出口return true;hasVisited[row][col] = true;if(hasPathCore(road, row - 1, col, tRow, tCol, hasVisited) || hasPathCore(road, row, col - 1, tRow, tCol, hasVisited) || hasPathCore(road, row + 1, col, tRow, tCol, hasVisited)|| hasPathCore(road, row, col + 1, tRow, tCol, hasVisited)) {return true;}hasVisited[row][col] = false;return false;}public static void main(String[] args) {boolean[][] road = {{true,true,true},{false,true,false},{false,true,true}};boolean[][] road2 = {{true ,true ,true ,false,false}, {false,false,true ,false,false}, {false,true ,true ,false,false}, {false,true ,false,false,false}, {false,true ,true ,true ,true }};Maze maze = new Maze();System.out.println(maze.hasPath(road2, 0, 0, 4, 4));}}
返回值为true;
再贴上完整版的代码,能找到所有路径并输出:
package com.qian.backtracing;import java.util.ArrayList;public class Maze2 {private int sum = 0;private ArrayList<ArrayList<String>> paths = new ArrayList<>();private ArrayList<String> path = new ArrayList<String>();public int hasPath(boolean[][] road, int sRow, int sCol, int tRow, int tCol) {boolean[][] hasVisited = new boolean[road.length][road[0].length];if (!road[sRow][sCol] || !road[tRow][tCol])return 0;hasPathCore(road, sRow, sCol, tRow, tCol, hasVisited,0);return sum;}/** * 回溯递归函数 * @param road 路线图 * @param row行号 * @param col列号 * @param tRow终点行号 * @param tCol终点列号 * @param hasVisited是否被访问数组 * @param depth访问深度 用于路径的添加 */public void hasPathCore(boolean[][] road, int row, int col, int tRow,int tCol, boolean[][] hasVisited,int depth) {int cols = road[0].length;int rows = road.length;if (col < 0 || col >= cols || row < 0 || row >= rows || !road[row][col] // 路是通的|| hasVisited[row][col]) {return;}path.add("(" + row + "," + col + ")");if (row == tRow && col == tCol) {// 递归函数的出口sum++;paths.add(new ArrayList<String>(path));path.remove(depth);return;} else {hasVisited[row][col] = true;hasPathCore(road, row - 1, col, tRow, tCol, hasVisited,depth + 1);hasPathCore(road, row, col - 1, tRow, tCol, hasVisited,depth + 1);hasPathCore(road, row + 1, col, tRow, tCol, hasVisited,depth + 1);hasPathCore(road, row, col + 1, tRow, tCol, hasVisited,depth + 1);// return true;path.remove(depth);hasVisited[row][col] = false;// return false;}}public static void main(String[] args) {boolean[][] road = { { true, true, true }, { false, true, false },{ false, true, true } };boolean[][] road2 = { { true , true , true , true , true },{ false, false, true , false, true },{ false, true , true , true , true },{ false, true , false, false, true },{ false, true , true , true , true } };//打印路径System.out.println("地图为:");for (int i = 0; i < road2.length; i++) {for (int j = 0; j < road2[0].length; j++) {if (road2[i][j])System.out.print("√,");elseSystem.out.print("x,");}System.out.println();}Maze2 maze = new Maze2();System.out.println("一共有" + maze.hasPath(road2, 0, 0, 4, 4) + "条路径");//打印路径System.out.println("分别为:");for (ArrayList<String> p : maze.paths) {System.out.println(p);}}}
输出结果为:
地图为:√,√,√,√,√,x,x,√,x,√,x,√,√,√,√,x,√,x,x,√,x,√,√,√,√,一共有4条路径分别为:[(0,0), (0,1), (0,2), (1,2), (2,2), (2,1), (3,1), (4,1), (4,2), (4,3), (4,4)][(0,0), (0,1), (0,2), (1,2), (2,2), (2,3), (2,4), (3,4), (4,4)][(0,0), (0,1), (0,2), (0,3), (0,4), (1,4), (2,4), (2,3), (2,2), (2,1), (3,1), (4,1), (4,2), (4,3), (4,4)][(0,0), (0,1), (0,2), (0,3), (0,4), (1,4), (2,4), (3,4), (4,4)]
1 0
- 回溯算法经典应用之—迷宫问题 (Java)
- 回溯算法经典应用之—N皇后问题 (Java)
- 回溯算法经典应用:迷宫求解
- 回溯算法之迷宫问题
- 回溯算法---迷宫问题
- 迷宫问题回溯算法
- 经典算法之迷宫问题
- C语言重解经典回溯算法案例-迷宫问题
- 回溯算法解决迷宫问题
- 经典回溯算法之N皇后问题
- 回溯经典算法之四皇后问题
- 经典回溯算法之n皇后问题
- C++搜索与回溯算法之迷宫问题
- 回溯算法解迷宫问题(java版)
- 数据结构与算法学习之路:迷宫问题——回溯思想找出所有路径
- 剑指Offer——回溯算法解迷宫问题(java版)
- 回溯算法解迷宫问题(C语言)
- 回溯算法解迷宫问题(C语言)
- 机器人走方格(dp)
- ViewPager滑动跟随的指示器
- C#封装程序集自定义类方法注释提示
- 关于Easyui 可编辑的数据表格中的计算
- window7安装mongoDB扩展
- 回溯算法经典应用之—迷宫问题 (Java)
- Linux /dev目录详解
- Quartz任务不执行问题
- Spring jackson message converter解析多余属性出错
- Eclipse 远程调试
- android手机获取手机号
- 欢迎使用CSDN-markdown编辑器
- Android的线程使用来更新UI----Thread、Handler、Looper、TimerTask等
- 常用DOS命令