前言

回溯法是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”, 这就是回溯法的定义;这个和穷举法有些关联,都在不断的试探;而下面从从九宫格、八皇后、数独问题、来理解回溯法

回溯法的应用

九宫格问题

我们要将4或者9个数或者16个数 n的n次方个数放入九宫格中,使得所有斜线和直线的数相加都等于相同的值,怎么解决这个问题;这就是通过回溯法可以解决的问题

解决问题的方法

  • 现在第一行的中间填第一个数1
  • 开始往右上角放数字,只要超过了上边,就放到下面,如果超过了左边就放右边

  • 当遇到右上角有数据,这里就是回溯了,放到当前数据的下面,然后继续往右上走

  • 就这样不断的往右上走,我们就能成下面的数独了

代码实现

我们首先定义创建九宫格

public static int n=5;public static int[][] array=new int[n][n];

主要逻辑

首先定义填入的数据,和定义起始位置

 int x=1;//要填入的数据//定义起始位置int row=0;int col=n/2;array[row][col]=1;

 数组的行和列的位置开始填写后面的数据

 //开始填写后面的数据while(x<n*n){//在选择下一位置的时候,先记录下现在的位置int tempRow=row;int tempCol=col;//向右上移动row--;if(row<0){row=n-1;}col++;if(col==n){col=0;}x++;if(array[row][col]==0){//如果右上没填,直接填入array[row][col]=x;}else{//如果没填,就放到当前位置的下面//还原row=tempRow;col=tempCol;row++;array[row][col]=x;}}
  • //在选择下一位置的时候,先记录下现在的位置int tempRow=row; int tempCol=col;
  • row--;就是往右上走,如果row<0 则 放到最下面 row=n-1;
  • col++; 如果col==n时 列号达到最大时, col=0;
  • if(array[row][col]==0){//如果右上没填,直接填入; 直接填入
  • 如果没填,就放到当前位置的下面 ;这里就涉及到还原  记录的 tempRow  进行还原

完整的代码

public static int n=5;public static int[][] array=new int[n][n];//逻辑public static void squaredUp(int[][] array){int x=1;//要填入的数据//定义起始位置int row=0;int col=n/2;array[row][col]=1;//开始填写后面的数据while(x<n*n){//在选择下一位置的时候,先记录下现在的位置int tempRow=row;int tempCol=col;//向右上移动row--;if(row<0){row=n-1;}col++;if(col==n){col=0;}x++;if(array[row][col]==0){//如果右上没填,直接填入array[row][col]=x;}else{//如果没填,就放到当前位置的下面//还原row=tempRow;col=tempCol;row++;array[row][col]=x;}}}

八皇后问题

也就是在国际象棋中,放一个棋子上,而这个棋子斜线和直线 上都可以吃棋子,因此在摆放时,棋盘上放一个皇后,而这个皇后相互之间不能吃,这就是八皇后问题

 先放一个棋子,然后放第二个棋子时,就要判定和其他棋子是否能吃到,在周围试探放如果行就放,不行就退回上一行,从上一行找能放的格子,到最后八行都能放下去的时候就是八皇后了

  • 也就是开始放到这里时 还可以

  • 然后我们继续往下试

当遇到下面的情况,我们无法摆,就要退回去,重新找另外种方式摆,直到摆满8个就算解决问题了,这就是回溯法

代码实现

设计思想,通过一维数组来表示二维数组,也就是  一维数组 ,用值表示哪个位置

  //下标表示行号    值表示列号public static int[] array=new int[8];
  • 然后处理8皇后的问题,首先考虑一个事情,要存放新的棋子时,我们要找到新的棋子与老的棋子不相交。也就是下面的图

  • 需要专门判断当前列放入的位置和以前放入位置有冲突 从0开始,判断是否有冲突
 for(int i=0;i<n;i++){//条件1  array[i]==array[n]  在一列上//条件2  abs(n-i)==abs(array[n]-array[i])if(array[i]==array[n] || Math.abs(n-i)==Math.abs(array[n]-array[i])){return false;}}return true;

这里 在同一列很简单,也就是array[n]=array[i]则表明有冲突了,array[n] 表示当前要填的固定的比如是上面的4 固定的,而array[i]表示 之前填的位置,看是否相等的,就是刚才已经确定的 ,这里就没填。

  • 怎么理解次对角线上的冲突拉,也就是

  • n-i绝对值等于array[n]-array[i] 的绝对值,这就是相同的,就在对角线上的

   最后

 //如果有结果了就退出if(row==8){printResult();System.out.println("---------");return;}//开始从第一列到最后一列一个个放入for(int col=0;col<8;col++){array[row]=col;if(judge(row)){//判断是否可以放入eightQueens(row+1);//就开始下一行}}

回溯是通过递归来做的,这就是解决8皇后问题

数独问题

规则

在9x9的方格上面,要求每一行和每一列从1到9的位置不重复的,然后每一个3x3的格子的数字,也是填1到9不能重复

  • 我们开始从第一个开始填写,看是否满足 ,能满足就继续往前填,不能满足就退回来重新填

这个和8皇后很像

这里放4就有问题,然后就要重新在返回写过

代码实现

我们先写一个随意的二维数组,占好位

 public static int[][] result=new int[9][9];
  • 判断数字是否可以用
 //判断行和列不重复for (int i = 0; i < 9; i++) {if(result[row][i]==number || result[i][col]==number){return false;}}

然后继续考虑3*3宫里面没有重复值

要求到其中一个没有重复值,我们只要 行列位置除以三就行

 //判断自已所在的宫里面没有重复值int tempRow=row/3;int tempCol=col/3;for (int i = 0; i < 3; i++) {for (int j = 0; j < 3; j++) {if(result[tempRow*3+i][tempCol*3+j]==number){return false;}}}

进行判断就行 是否有重复值就行

  • 我们从第一个开始往后填
public static void sudoku(){sudoku(0,0);}public static void sudoku(int i,int j){if(i==8 && j==9){printResult();return;}if(j==9){//横着放的时候,如果到了最右边,就回到下一行的第一个i++;j=0;}if(result[i][j]==0){//如果是空格for (int k = 1; k <= 9; k++) {if(judge(i,j,k)){result[i][j]=k;sudoku(i,j+1);//让前一次的格子还原result[i][j]=0;}}}else{sudoku(i,j+1);}}

这里不断往后放的时候,我们得还原空格,得还原回来。也就是等于0,就是递归下去。

这有很多组解得。

总结

最后学习回溯法,和递归关系比较密切,穷举法,效率大家能想到比较低,我们是为了解决某些问题用回溯法,也算是我们常用经典得算法。

五大经典算法之回溯法及其应用相关推荐

  1. 五大经典算法之回溯法

    一.基本概念   回溯法,又称为试探法,按选优条件向前不断搜索,以达到目标.但是当探索到某一步时,如果发现原先选择并不优或达不到目标,就会退回一步重新选择,这种达不到目的就退回再走的算法称为回溯法. ...

  2. 第39级台阶回溯算法c语言,五大经典算法之回溯法 - osc_9ipdey7e的个人空间 - OSCHINA - 中文开源技术交流社区...

    一.基本概念 回溯法,又称为试探法,按选优条件向前不断搜索,以达到目标.但是当探索到某一步时,如果发现原先选择并不优或达不到目标,就会退回一步重新选择,这种达不到目的就退回再走的算法称为回溯法. 与穷 ...

  3. 五大常用算法之回溯法详解及经典例题

    一. 回溯法 – 深度优先搜素 1. 简单概述 回溯法思路的简单描述是:把问题的解空间转化成了图或者树的结构表示,然后使用深度优先搜索策略进行遍历,遍历的过程中记录和寻找所有可行解或者最优解. 基本思 ...

  4. [回溯算法] 五大常用算法之回溯法

    算法入门6:回溯法 一. 回溯法 – 深度优先搜素 1. 简单概述 回溯法思路的简单描述是:把问题的解空间转化成了图或者树的结构表示,然后使用深度优先搜索策略进行遍历,遍历的过程中记录和寻找所有可行解 ...

  5. 五大经典算法(贪婪、动态规划、分治、回溯、分支限界法)及其联系和比较

    一.贪心法 贪心算法的含义: 贪心算法(也叫贪婪算法)是指在对问题求解时,总是做出在当前看来是最好的选择.也就是说,不从整体最优上加以考虑,只做出在某种意义上的局部最优解.贪心算法不是对所有问题都能得 ...

  6. 五大常用算法一(回溯,随机化,动态规划)

    五大常用算法一(回溯,随机化,动态规划) 回溯算法 回溯法: 也称为试探法,它并不考虑问题规模的大小,而是从问题的最明显的最小规模开始逐步求解出可能的答案,并以此慢慢地扩大问题规模,迭代地逼近最终问题 ...

  7. C++——《算法分析与设计》实验报告——贪心算法与回溯法

    实验名称: 贪心算法与回溯法 实验地点: 实验目的: 1.理解贪心算法与回溯法的概念: 2.掌握贪心算法与回溯法的基本要素: 3.掌握贪心算法与回溯法的解题步骤与算法柜架: 4.通过应用范例学习贪心算 ...

  8. LeetCode算法总结-回溯法与深度优先搜索

    转载自  LeetCode算法总结-回溯法与深度优先搜索 回溯法(探索与回溯法)是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标.但当探索到某一步时,发现原先选择并不优或达不到目标,就退 ...

  9. C++——《算法分析》实验叁——贪心算法与回溯法

    实验目的: 1.理解贪心算法与回溯法的概念: 2.掌握贪心算法与回溯法的基本要素: 3.掌握贪心算法与回溯法的解题步骤与算法柜架: 4.通过应用范例学习贪心算法与回溯法的设计技巧与策略: 实验原理 1 ...

最新文章

  1. 360推两款无刘海新机,主打安全和AI,起售价1199
  2. linux uefo引导 win_基于UEFI和GPT模式下U盘安装windows8.1和Linux双启动教程
  3. SQL Server数据库设置自动备份策略
  4. 前端学习(325):javascript历史
  5. JS——基础知识--变量类型和变量计算
  6. 【Kafka】 kafka 启动 Connection to node 1 could not be established. Broker may not be available
  7. C语言丨比较浮点数的大小
  8. VMWare NSX安全生产和DMZ用例的详细设计指南
  9. pycharm设置中文
  10. 如何导入超大mysql数据库备份文件_导入超大MySQL数据库备份文件.sql工具-BigDump使用方法...
  11. 【html笔记】html介绍和语法入门
  12. Python菜鸟之路:原生Ajax/Jquery Ajax/IFrame Ajax的选用
  13. Navigation Timing API 准确掌握浏览器各项开销时间
  14. HDOJ4699 Editor 栈
  15. 拯救rm-rf删库事故
  16. T70次列车(乌鲁木齐 到 北京)的列车时刻表
  17. 数据库的应用之(智慧城市)
  18. R语言机器学习 格兰杰因果关系检验(Granger cointegratance)
  19. 程序员崩溃了!想拿的年终奖怎么说黄就黄?!
  20. 归一化处理的目的和意义及其MATLAB方法

热门文章

  1. 悬镜 linux防黑加固平台,悬镜服务器卫士防黑加固效果更明显
  2. 导电滑环的型号有哪些,工作寿命多长?
  3. 将图片显示到layui的数据表格上
  4. Win10家庭版安装Docker Desktop后无法重启,强制重启后无法联网问题的解决
  5. ABAP OpenSQL使用索引(HINTS)的参考NOTE记录
  6. 如何给目标机器人建模并仿真【数学/控制意义】
  7. Python的学习笔记案例6--判断密码强度1.0
  8. 当咖啡遇上黑科技,咖啡爱好者有福了?
  9. JS 的省市区三级联动
  10. 从零开始带你做短视频自媒体,0基础新手小白也能学会,抓紧收藏