多字段回溯 mysql_回溯算法 | 追忆那些年曾难倒我们的八皇后问题

前言

说起八皇后问题,它是一道回溯算法类的经典问题,也可能是我们大部分人在上数据结构或者算法课上遇到过的最难的一道题……

fb01cbf7d425e72a5bf1f09faa6206ce.png在这里插入图片描述

第一次遇到它的时候应该是大一下或者大二这个期间,这个时间对啥都懵懵懂懂,啥都想学却发现好像啥都挺难的,八皇后同样把那个时候的我阻拦在外,我记得很清楚当时大二初我们学业导师给我们开班会时候讲到的一句话很清晰:"如果没有认真的学习算法他怎么可能解出八皇后的代码呢"。

确实,那个时候的我搞不懂递归,回溯也没听过,连Java的集合都没用明白,毫无逻辑可言,八皇后对我来说确实就是无从下手。

但今天,我可以吊打八皇后了,和你们一起白银万两,佳丽三十。

3113d47fab6916af97d363fdb2fb1910.png在这里插入图片描述

浅谈递归

对于递归算法,我觉得掌握递归是入门数据结构与算法的关键,因为后面学习很多操作涉及到递归,例如链表的一些操作、树的遍历和一些操作、图的dfs、快排、归并排序等等。

在这里插入图片描述

递归的实质还是借助栈实现一些操作,利用递归能够完成的操作使用栈都能够完成,并且利用栈的话可以很好的控制停止,效率更高(递归是一个来回的过程回来的时候需要特判)。

递归实现和栈实现操作的区别,递归对我们来说更简洁巧妙,并且用多了会发现很多问题的处理上递归的思考方式更偏向人的思考方式,而栈的话就是老老实实用计算机(数据结构特性)的思维去思考问题。这个你可以参考二叉树的遍历方式递归和非递归版本,复杂性一目了然。

从递归算法的特征上来看,递归算法的问题都是父问题可以用过一定关系转化为子问题。即从后往前推导的过程,一般通过一个参数来表示当前的层级。

而递归的主要特点如下:自己调用自己

递归通常不在意具体操作,只关心初始条件和上下层的变化关系。

递归函数需要有临界停止点,即递归不能无限制的执行下去。通常这个点为必须经过的一个数。

递归可以被栈替代。有些递归可以优化。比如遇到重复性的可以借助空间内存记录而减少递归的次数。

在这里插入图片描述

而通常递归算法的一个流程大致为:定义递归算法及参数

- 停止递归算法条件

- (可存在)其他逻辑

- 递归调用(参数需要改变)

- (可存在)其他逻辑

如果还是不理解的话就要看我的另一篇文章了:数据结构与算法—递归算法(从阶乘、斐波那契到汉诺塔的递归图解),写的是真的好!

回溯算法

谈完递归,你可能明白有这么一种方法可以使用,但你可能感觉单单的递归和八皇后还是很难扯上关系,是的没错,所以我来讲回溯算法了。

这里插个小插曲。前天(真的前天)有个舍友我们宿舍一起聊天的时候谈到回溯算法,他说回shuo(朔)算法,我们差异的纠正了一下是回su(素)算法,他竟然读错了四年……不知道路过的你们有没有读错的。

在这里插入图片描述

咱们言归正传,算法界中,有五大常用算法:贪心算法、分治算法、动态规划算法、回溯算法、分支界限算法。咱们回溯算法就是五大之一,因为回溯算法能够解决很多实际的问题,尽管很多时候复杂度可能不太小,但大部分情况都能得到一个不错的结果。

对于回溯法的定义,百度百科是这么定义的:回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”返回,尝试别的路径。回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。许多复杂的,规模较大的问题都可以使用回溯法,有“通用解题方法”的美称。

对于回溯法,它的核心就是试探和复原。这个自动化的过程就是利用递归去执行,在递归函数执行前去修改尝试,满足条件后向下递归试探,试探完毕后需要将数值复原。在这个试探的过程中找到我们所需要的一个或者所有解。这个我们也俗称暴力。

在这里插入图片描述

啥?没听懂?好,那我就再讲讲,你应该知道深度优先搜索(dfs)吧?其实回溯算法就是一种特殊的dfs。之所以叫回溯,就是因为这类算法在运用递归都有个复原的过程,所以前面的操作就相当于试探一样。而这类算法一般常常配对一个或多个boolean类型的数组用来标记试探途中用过的点。

举个例子,我们知道回溯算法用来求所有数字的排列顺序。我们分析其中一个顺序。比如数列6 8 9这个序列的话,我们用来求它的排列顺序。

对于代码块来说,这可能很容易实现:import java.util.Arrays;

public class test{

public static void main(String[] args){

int arr[]={6,8,9};//需要排列组合的数组

int val[]={0,0,0};//临时储存的数组

boolean jud[] = new boolean[arr.length];// 判断是否被用

dfs(arr,val, jud,  0,"");//用一个字符串长度更直观看结果

}

private static void dfs(int[] arr, int val[],boolean[] jud, int index,String s){

System.out.println(s+Arrays.toString(val));

if (index == arr.length){ }//停止递归条件

else{

for (int i = 0; i 

if (!jud[i]) {//当前不能用的

int team=val[index];

val[index] = arr[i];

jud[i] = true;// 下层不能在用

dfs(arr, val, jud, index + 1,s+"  _  ");

jud[i] = false;// 还原

val[index]=team;

}

}

}

}

}

而执行的结果为:

在这里插入图片描述

这里再配张图理解:

在这里插入图片描述

而通常回溯算法的一个流程大致为:

定义回溯算法及参数

- (符合条件)跳出

- (不符合)不跳出:

- - 遍历需要操作的列表&&该元素可操作&&可以继续试探

- - - 标记该元素已使用以及其他操作

- - - 递归调用(参数改变)

- - - 清除该元素标记以及其他操作

也就是在使用数组进行回溯的时候,使用过的时候需要标记子递归不能再使用防止死循环,而当回来的时候需要解封该位置,以便该编号位置被其他兄弟使用之后这个数值在后面能够再次使用!而如果使用List或者StringBuilder等动态空间用来进行回溯的时候记得同样的复原,删了要记得增,减了要记得加。搞明白这些,我想回溯算法也应该难不倒你了吧。

八皇后问题

掌握了回溯算法的关键,八皇后问题多思考就可以想的出来了。前面的讲解都是为了解决八皇后问题做铺垫。首先,我们认真的看下八皇后问题描述。

八皇后问题(英文:Eight queens),是由国际西洋棋棋手马克斯·贝瑟尔于1848年提出的问题,是回溯算法的典型案例。问题表述为:在8×8格的国际象棋上摆放8个皇后,使其不能互相***,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。如果经过±90度、±180度旋转,和对角线对称变换的摆法看成一类,共有42类。计算机发明后,有多种计算机语言可以编程解决此问题。在这里插入图片描述

我们该怎么思考这种问题呢?也就是从何入手呢?从限制条件入手

八皇后问题有以下限制条件:8 x 8的方格

每行一个,共八行(0-7)

每列一个,共八列(0-7)

每左斜杠一个,共十五左斜杠(0-14)

每右斜杠一个,共十五右斜杠(0-14)

当看到这些限制条件,肯定想到这么多限制条件需要判断。判断的话当然就是借助boolean数组啦。还是一维的8个大小,所以我们首先用4个boolean数组用来判断各自的条件是否被满足。

表示这个图的话我们可以使用一个int类型数组表示,0表示没有,1表示有皇后。

那么如何去设计这个算法呢?这个并不是每个格子都有数字,所以在进行回溯的时候不应该每个格子每个格子进行向下递归(同行互斥),也就是递归到当前层的时候,循环遍历该层的八种情况进行试探(每个都试探),如果不满足条件的就不操作而被终止掉,但该行每个满足条件的需要递归的时候需要进入到下一行。

当然你需要提前知道当前位置横纵坐标怎们知道对应的boolean位置(位置从0号开始计算)。例如位置p(x,y)中对应的位置为:hang[] : x  每一行就是对应的i。

lie[] : y 每一列就是对应的j。

zuoxie[] : x+y 规定顺序为左上到右下

youxie[] : x+(7-y) 规定顺序为右上到左下(个人习惯)

de63bb536f6f6edd0882051aef5ad530.png在这里插入图片描述

好啦,该算法的实现代码为:import java.util.Arrays;

public class EightQueens{

static  int allnum=0;

public static void main(String[] args){

boolean hang[]=new boolean[8];//行

boolean lie[]=new boolean[8];//列

boolean zuoxie[]=new boolean[15];//左斜杠

boolean youxie[]=new boolean[15];//右斜杠

int map[][]=new int[8][8];//地图

dfs(0,hang,lie,zuoxie,youxie,map);//进行下去

}

private static void dfs(int hindex, boolean[] hang, boolean[] lie, boolean[] zuoxie, boolean[] youxie, int[][] map){

if(hindex==8){

allnum++;

printmap(map);//输出map

}

else{

//hindex为行  i为具体的某一列

for(int i=0;i<8;i++)

{

if(!hang[hindex]&&!lie[i]&&!zuoxie[hindex+i]&&!youxie[hindex+(7-i)])

{

hang[hindex]=true;//试探

lie[i]=true;

zuoxie[hindex+i]=true;

youxie[hindex+(7-i)]=true;

map[hindex][i]=1;

dfs(hindex+1,hang,lie,zuoxie,youxie,map);//dfs

hang[hindex]=false;//还原

lie[i]=false;

zuoxie[hindex+i]=false;

youxie[hindex+(7-i)]=false;

map[hindex][i]=0;

}

}

}

}

//输出地图

private static void printmap(int[][] map){

System.out.println("第"+allnum+"个排列为");

for(int a[]:map)

{

System.out.println(Arrays.toString(a));

}

}

}

跑一边就知道到底有多少种皇后,最终是92种皇后排列方式,不得不说能用数学方法接出来的是真的牛叉。

406c017e19fa6300dec396b643bb4824.png在这里插入图片描述

八皇后变种

此时我想八皇后问题已经搞得明明白白了,但是智慧的人们总是想出各种方法变化题目想难到我们,这种八皇后问题有很多变种,例如n皇后,数独等问题。

这里就简单讲讲两数独问题的变种。

力扣36 有效的数独

在这里插入图片描述

像这种题需要考虑和八皇后还是很像,改成9*9,只不过在具体处理需要考虑横、竖和3x3小方格。

当然这题比较简单,还有一题就比较麻烦了 力扣37解数独。

在这里插入图片描述

在这里插入图片描述

这一题有难度的就是需要我们每个位置都有数据都要去试探。

这种二维的回溯需要考虑一些问题,我们对于每一行每一行考虑。每一行已经预有一些数据事先标记,在从开始试探放值,满足条件后向下递归试探。一直到结束如果都满足那么就可以结束返回数组值。

这里的话有两点需要注意的在这里提一下:用二维两个参数进行递归回溯判断起来谁加谁减比较麻烦,所以我们用一个参数index用它来计算横纵坐标进行转换,这样就减少二维递归的一些麻烦。

回溯是一个来回的过程,在回来的过程正常情况需要将数据改回去,但是如果已经知道结果就没必要再改回去可以直接停止放置回溯造成值的修改(这里我用了一个isfinish的boolean类型进行判断)。

代码可以参考为:

c8e8660370b5481f3b55cb5b081a788e.png在这里插入图片描述

结语

好啦,不知道这个专题结束之后能否能够掌握这个八皇后的回溯算法以及思想,能否理清递归,回溯,深搜以及八皇后为关系?

总的来说递归更注重一种方式,自己调用自己。

回溯更注重试探和复原,这个过程一般借助递归。

dfs深度优先搜素,一般用栈或者递归去实现,如果用递归可能会复原也可能不复原数据,所以回溯是深搜的一种。

八皇后是经典回溯算法解决的问题,你说深度优先搜素其实也没问题,但回溯更能精准的描述算法特征。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/485858.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

这一年,宇宙“面目”愈发清晰

来源&#xff1a;科技日报 深邃的星空&#xff0c;埋藏着无数奥秘&#xff0c;叩问2020年的宇宙苍穹&#xff0c;阵阵回响唤起惊奇与敬畏无数&#xff1a;人类首次在银河系外发现氧气、绘制迄今最大宇宙三维地图、发现“不可能存在”的中等质量黑洞……宇宙的秘密&#xff0c;正…

mysql connector net 6.9.3_MySQL Connector/Net 6.9.3 发布 MySQL Connector/Net 6.9.3下载

MySQL Connector/ODBC 是 MySQL 数据库的官方 .NET 平台驱动程序。MySQL Connector/Net 6.9.3 发布&#xff0c;此版本是 6.9 系列的第一个 GA 版本。Bugs 修复Adding a new column to an existing model as identity and PK failed when applying the migration. (Bug #192863…

在失败中学习,MIT新研究显示,机器可以像婴儿一样学会理解人类目标

大数据文摘出品来源&#xff1a;MIT编译&#xff1a;周熙在Warneken和Tomasello关于人类社会智力的经典实验中&#xff0c;一个18月大蹒跚学步的幼儿看着一个男人抱着一堆书走向一个未开封的柜子。当男子到达柜子时&#xff0c;他笨拙地将书在柜门上撞了几下&#xff0c;然后发…

django http404 详解

【引子】 今天在看django的官方文档的时候看到get_object_or_404这个函数感觉比较奇怪。这个主要来自于它的功能&#xff0c;如果要查询的对象 存在那么就返回对象&#xff1b;如果对象不存在那么就要报404 Not Found &#xff1b;但是404 Not Found并不是它的返回值&#xff0…

这一年,科学高度不断刷新

来源&#xff1a;科技日报●存算一体架构在手写数字集上的识别准确率达到96.19%●截至12月14日21时&#xff0c;“天问一号”探测器已在轨飞行144天&#xff0c;飞行里程约3.6亿公里&#xff0c;距离地球超过1亿公里●嫦娥五号经历了11个阶段、23天的在轨工作&#xff0c;采集了…

python天天向上的力量三天打鱼两天晒网_017 示例3-天天向上的力量-Go语言中文社区...

一、"天天向上的力量"问题分析1.1 天天向上的力量基本问题&#xff1a;持续的价值一年365天&#xff0c;每天进步1%&#xff0c;累计进步多少呢&#xff1f;(1.01^{365})一年365天&#xff0c;每天退步1%&#xff0c;累计剩下多少呢&#xff1f;(0.99^{365})1.2 需求…

CNS三大刊2020年年度最佳论文全部出炉!脑科学一共4篇,我国学者入选1篇!

来源&#xff1a; brainnews编辑部、inature编辑部来源&#xff1a;生物谷旗下细胞公众号&#xff0c;药明康德团队旗下学术经纬公众号Cell ,Nature和Science 三大期刊2020年年度最佳论文全部公布&#xff0c;brainnews编辑部摘选其中跟脑科学相关的文章&#xff0c;跟大家一起…

redis创建像mysql表结构_Redis数据结构列表实现

双向链表linkedlistRedis实现的是标准的双向链表。链表节点定义&#xff1a;链表定义&#xff1a;总结链表实现&#xff1a;1.每个节点有前后节点指针&#xff0c;且第一个节点的指针为NULL,最后一个节点的指针为NULL(无环)。2.对双链表进行封装&#xff0c;链表第一个节点和最…

神经符号系统、因果推理、跨学科交互,李飞飞、Judea Pearl等16名学者共同探讨AI未来...

来源&#xff1a;机器之心去年&#xff0c;纽约大学心理学和神经科学教授 Gary Marcus 和深度学习先驱、2018 年图灵奖得主 Yoshua Bengio 就 AI 技术的发展方向展开了一场现场辩论。今年&#xff0c;Gary Marcus 与 Montreal.AI 负责人 Vincent Boucher 举办了第二场辩论。这次…

数字孪生城市应用【案例集】,附下载

来源&#xff1a;中国信通院等数字孪生城市经过三年的概念培育期&#xff0c;目前已经步入落地实施阶段&#xff0c;各地不同程度地推进数字孪生城市规划建设和行业应用创新实践。中国信息通信研究院联合数字孪生城市生态圈合作伙伴&#xff0c;在推出《数字孪生城市白皮书&…

安乐高机器人图纸_乐高机器人拼装图纸 | 手游网游页游攻略大全

发布时间&#xff1a;2015-12-26这是一个非常酷的乐高机器人,可以绘画的机器人.意大利工程师Daniele Benedettelli制造了这个乐高机器人,称其为"LEGONARDO".他的绘画动作是通过编程实现的,他将不会停止,直到你 ...标签&#xff1a;游戏资讯 八卦杂谈发布时间&#xf…

重磅!中国微纳机器人技术取得新突破,实现肿瘤的可视化精准治疗!

来源&#xff1a;机器人大讲堂科技的发展会带动相关领域共同进步&#xff0c;在科技进步越来越快的今天&#xff0c;一项技术的进步往往会同时打开好几个领域的技术难关&#xff0c;产生连锁反应&#xff0c;科技的边界也逐渐模糊&#xff0c;以新材料石墨烯的研究为例&#xf…

什么是本体论?

来源&#xff1a;人机与认知实验室【世界有无本体还是互为本体&#xff1f;这是两个非常有意思的问题&#xff0c;从牛顿绝对主义角度应该有&#xff0c;从爱翁相对主义应该无&#xff0c;从未来的发展看&#xff0c;应该是“变”——也许就是“易”&#xff1f;&#xff01;主…

亚马逊首席技术官预测2021年将改变世界的八大技术趋势

来源&#xff1a;世界科技研究与发展2020年12月17日&#xff0c;亚马逊全球副总裁、首席技术官维尔纳•沃格尔&#xff08;Werner Vogels&#xff09;博士在亚马逊re:Invent全球大会上发表压轴演讲&#xff0c;分享了他对2021年科技趋势的预测。回顾2020年&#xff0c;Werner表…

《城市大脑全球标准研究报告2020》摘要内容

‍‍前言&#xff1a;《城市大脑全球标准研究报告2020》12月23在京正式发布&#xff0c;有近70位专家、领导和媒体记者出席了发布会&#xff0c;会后包括新华社、工人日报、中新社、科技日报、中国科学报、中国社会科学报、中国建设报、经济日报、中国经营报、经济观察报&#…

EasyExcel中处理内容占多个单元格

在一些业务需求中内容需要占用多个单元格的情况&#xff0c;如下图&#xff1a; 或者是这样 这样 总有一些奇怪怪的需求。 不过使用EasyExcel可以轻松处理这些变态的需求。EasyExcel中提供了ContentLoopMerge 注解就是为了处理这种问题的。下面先看看如何使用ContentLoopMe…

2021十大科技趋势来了!阿里巴巴达摩院全新发布

来源&#xff1a; 阿里技术阿里巴巴达摩院发布2021十大科技趋势&#xff0c;这是达摩院成立三年以来第三次发布年度科技趋势。2020年是不平凡的一年&#xff0c;经历疫情的洗礼&#xff0c;许多行业重启向上而生的螺旋&#xff0c;但疫情并未阻挡科技前进的脚步&#xff0c;量子…

从GPT-3到DETR,一起来盘点2020有哪些突破?

来源&#xff1a;深度学习技术前沿2020年是巨大飞跃的一年。从OpenAI的GPT-3&#xff0c;再到AlphaFold&#xff0c;都是令人振奋的成就。与此同时&#xff0c;数据科学在机器学习、自然语言处理&#xff08;NLP&#xff09;、计算机视觉等领域中蓬勃发展。一起来逐一盘点2020的…

我国5G基站达71.8万个,助力人工智能发展!

来源&#xff1a;新华社2020中国人工智能高峰论坛暨中国人工智能大赛成果发布会23日在厦门举办。论坛上&#xff0c;中国工业和信息化部副部长刘烈宏介绍&#xff0c;截至今年11月&#xff0c;我国累计建成5G基站71.8万个&#xff0c;为人工智能海量数据的成长和传输提供了坚实…

《自然》预测2021年值得关注的科学事件

来源&#xff1a;世界科技研究与发展作者&#xff1a;黄小容2020年12月22日&#xff0c;Nature官网发布了对2021年最值得关注科学事件的预测。1 气候变化问题卷土重来