回溯算法的使用
来源:互联网 发布:手机图片搜索软件 编辑:程序博客网 时间:2024/06/05 11:03
回溯算法定义:
回溯算法也叫试探法,它是一种系统地搜索问题的解的方法。回溯算法的基本思想是:从一条路往前走,能进则进,不能进则退回来,换一条路再试。
回溯算法思想描述:
在包含问题的所有解的解空间树中,按照深度优先搜索的策略,从根结点出发深度探索解空间树。当探索到某一结点时,要先判断该结点是否包含问题的解,如果包含,就从该结点出发继续探索下去,如果该结点不包含问题的解,则逐层向其祖先结点回溯。(其实回溯法就是对隐式图的深度优先搜索算法)。 若用回溯法求问题的所有解时,要回溯到根,且根结点的所有可行的子树都要已被搜索遍才结束。 而若使用回溯法求任一个解时,只要搜索到问题的一个解就可以结束。
解题步骤:
1.定义一个解空间,它包含问题的解;
2.利用适于搜索的方法组织解空间;
3.利用深度优先法搜索解空间;
4.利用限界函数避免移动到不可能产生解的子空间。
回溯算法的使用
八皇后
问题描述:
在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
/** * 八皇后 * Created by MGL on 2017/2/23. */public class EightQueens01 { public static void main(String[] args) { EightQueens01 eightQueens01 = new EightQueens01(); eightQueens01.search(); } /** * 初始化 */ public void search() { //横向同一栏是否有皇后,1表示有 int[] column = new int[9]; //右上至左下是否有皇后 int[] rup = new int[17]; //左上至右下是否有皇后 int[] lup = new int[17]; //储存保存的皇后的位置(如queen[1] = 3) //代表在第一行的第三个位置有个皇后 int[] queen = new int[9]; System.out.println(search(1, column, rup, lup, queen, 0)); } /** * 进行查找 * @param i 第几行 * @param column 横向同一栏是否有皇后,1表示有 * @param rup 右上至左下是否有皇后 * @param lup 左上至右下是否有皇后 * @param queen 答案 * @param count 当前解的个数 * @return */ private int search(int i, int[] column, int[] rup, int[] lup, int[] queen, int count) { if (i > 8) { return show(count, queen); } else { for (int j = 1; j <= 8; j++) { //判断同一横栏是否有皇后 //判断右上至左下是否有皇后 判断左上至右下是否有皇后 if ((column[j] == 0) && (rup[i + j] == 0) && (lup[i - j + 8] == 0)) { //保存结果 queen[i] = j; column[j] = rup[i + j] = lup[i - j + 8] = 1; //跳到下一行继续探索 count = search(i + 1, column, rup, lup, queen, count); column[j] = rup[i + j] = lup[i - j + 8] = 0; } } } return count; } /** * 打印皇后结果 * @param count * @param queen * @return */ private int show(int count, int[] queen) { count++; System.out.println("\n解答" + count); for (int y = 1; y <= 8; y++) { for (int x = 1; x <= 8; x++) { if (queen[y] == x) { System.out.print("Q"); } else { System.out.print("."); } } System.out.print("\n"); } return count; }}
矩阵中的路径
问题描述:
请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。 例如[a b c e s f c s a d e e]是3*4矩阵,其包含字符串”bcced”的路径,但是矩阵中不包含“abcb”路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。
public class Solution { public boolean hasPath(char[] matrix, int rows, int cols, char[] str) { //矩阵中每一个格子作为路径的起点 for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { int[] flag = new int[matrix.length]; if (hasPath(matrix, rows, cols, str, i, j, 0, flag)) { return true; } } } return false; } /** * 查找 * * @param matrix 使用以为坐标储存二维坐标的数据 * @param rows 该二维数组有多少行 * @param cols 该二维数组有多少列 * @param str 要查找的路径 * @param i 当前的横坐标 * @param j 当前的纵坐标 * @param k 查找的次数 * @param flag 经过的坐标(经过之后设置为1) * @return */ private boolean hasPath(char[] matrix, int rows, int cols, char[] str, int i, int j, int k, int[] flag) { //计算当前坐标在一维数组中的位置 int index = cols * i + j; //判断 计算的位置是否越界 判断横坐标纵坐标是否越界 //判断是否曾经经过坐标 判断是否相等 if (index >= matrix.length || i < 0 || j < 0 || i > rows || j > cols || flag[index] == 1 || matrix[index] != str[k]) { return false; } if (k == str.length - 1) { return true; } if (matrix[index] == str[k]) { flag[index] = 1; //向左查找 return hasPath(matrix, rows, cols, str, i, j - 1, k + 1, flag) ||//向下查找 hasPath(matrix, rows, cols, str, i + 1, j, k + 1, flag) ||//向右查找hasPath(matrix, rows, cols, str, i, j + 1, k + 1, flag) ||//向上查找hasPath(matrix, rows, cols, str, i - 1, j, k + 1, flag); } return false; } public static void main(String[] args) { Solution solution = new Solution(); System.out.println(solution.hasPath("ABCESFCSADEE".toCharArray(), 3, 4, "ABCCED".toCharArray()) + "[true]");// true //ABCE //SEE //SFCS //ADEE System.out.println(solution.hasPath("ABCESFCSADEE".toCharArray(), 3, 4, "SEE".toCharArray()) + "[true]");// true //ABCE //ABCB //SFCS //ADEE System.out.println(solution.hasPath("ABCESFCSADEE".toCharArray(), 3, 4, "ABCB".toCharArray()) + "[false]");// false //ABCEHJIG //SLHECCEIDEJFGGFIE //SFCSLOPQ //ADEEMNOE //ADIDEJFM //VCEIFGGS System.out.println(solution.hasPath("ABCEHJIGSFCSLOPQADEEMNOEADIDEJFMVCEIFGGS".toCharArray(), 5, 8, "SLHECCEIDEJFGGFIE".toCharArray()) + "[true]");// true //ABCEHJIG //SGGFIECVAASABCEHJIGQEM //SFCSLOPQ // //ADEEMNOE //ADIDEJFM //VCEIFGGS System.out.println(solution.hasPath("ABCEHJIGSFCSLOPQADEEMNOEADIDEJFMVCEIFGGS".toCharArray(), 5, 8, "SGGFIECVAASABCEHJIGQEM".toCharArray()) + "[true]");// true //ABCEHJIG //SGGFIECVAASABCEEJIGOEM //SFCSLOPQ //ADEEMNOE //ADIDEJFM //VCEIFGGS System.out.println(solution.hasPath("ABCEHJIGSFCSLOPQADEEMNOEADIDEJFMVCEIFGGS".toCharArray(), 5, 8, "SGGFIECVAASABCEEJIGOEM".toCharArray()) + "[false]");// false //ABCEHJIG //SGGFIECVAASABCEHJIGQEMS //SFCSLOPQ //ADEEMNOE //ADIDEJFM //VCEIFGGS System.out.println(solution.hasPath("ABCEHJIGSFCSLOPQADEEMNOEADIDEJFMVCEIFGGS".toCharArray(), 5, 8, "SGGFIECVAASABCEHJIGQEMS".toCharArray()) + "[false]");// false //AAAA //AAAAAAAAAAAA //AAAA //AAAA System.out.println(solution.hasPath("AAAAAAAAAAAA".toCharArray(), 3, 4, "AAAAAAAAAAAA".toCharArray()) + "[true]");// true //AAAA //AAAAAAAAAAAAA //AAAA //AAAA System.out.println(solution.hasPath("AAAAAAAAAAAA".toCharArray(), 3, 4, "AAAAAAAAAAAAA".toCharArray()) + "[false]");// false }}
- 回溯算法的使用
- C++ 回溯算法 (递归的使用)
- 回溯算法的理解与使用
- 回溯算法的形式
- 回溯算法的理解
- N皇后的回溯算法
- “皇后”问题的回溯算法
- 图着色的回溯算法
- 回溯算法写的组合
- 回溯的那些个算法
- 经典问题的回溯算法
- 背包问题的回溯算法
- 彻头彻尾的理解回溯算法
- 回溯法的通用算法
- 回溯法的算法框架
- 回溯算法的基本要点
- 回溯——用蒙特卡洛算法估计回溯算法的效率
- 回溯算法
- 【Coursera】编程题 Percolation
- Jquery——Day2(基础事件)
- 编码与解码-UVA
- servlet纲要
- java基础学习--------第三章流程控制
- 回溯算法的使用
- hdu 2955 Robberies
- shell(2)脚本执行方式
- 深度神经网络(DNN)模型与前向传播算法
- maven项目打包发布时跳过测试
- USACO 2013open :yinyang(treap+启发式合并)
- 信息安全系统的组织管理
- Spring Cloud系列二 之 Ribbon负载均衡
- [LNMPA搭建二]PHP详细安装搭建