算法学习笔记(9)-回溯算法与八皇后问题

八皇后问题--递归回溯算法(Python实现) 前两天做牛客的时候遇到了一个字符串的全排列问题。顺便回顾一下八皇后问题。(后附Python代码)如何解决八皇后问题?所谓递归回溯,本质上是一种枚举法。这种方法从棋盘的第一行开始尝试摆放第一个皇后,摆放成功后,递归一层,再遵循规则在棋盘第二行来摆放第二个皇后。如果当前位置无法摆放,则向右移动一格再次尝试,如果摆放成功,则继续递归一层,摆放第三个皇后......如果某一层看遍了所有格子,都无法成功摆放... 阅读详情

回溯算法也叫试探搜索算法,它是一种类似于暴力枚举的搜索方法, 但是不同的是在回溯的过程中存在剪枝和状态的自转化,所以对于暴力枚举类问题,往往选择使用回溯算法,以达到优化时间和空间的目的

一.用回溯算法解决问题的一般步骤

1、 针对所给问题,定义问题的解空间,它至少包含问题的一个(最优)解。
2 、确定易于搜索的解空间结构,使得能用回溯法方便地搜索整个解空间 。
3 、以深度优先的方式搜索解空间,并且在搜索过程中用剪枝函数避免无效搜索。

我们用八皇后问题来理解一下回溯算法的执行步骤:

二. 八皇后问题

八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋盘上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。

我们可以先解决这个问题的简化版本,即四皇后问题,四皇后问题指的是在4×4的国际象棋盘上摆放四个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。

2.1 回溯思路

解决这个问题的思路是这样子的:

1.首先我们在棋盘的左下角摆放一个皇后,此时还有3个皇后要摆放
2.接下来我们在棋盘的第二行的某个位置摆放一个皇后,使其不会相互攻击;观察第三行是否可以摆放得下皇后,如果不可以则将该皇后挪到下一个可行的列
3.接下来在棋盘的第三行某个位置摆放一个皇后,使其不会相互攻击,观察第四行是否可以摆放得下皇后,如果不可以则将该皇后挪到下一个可行的列
4.接下来在棋盘的第四行某个位置摆放一个皇后,使其不会相互攻击,此时4个皇后摆放完毕,这是四皇后问题的一个解

其中2,3步中的"观察第三行是否可以摆放得下皇后"这个过程称之为"剪枝",即剪去了绝对不可能成立的情况;而"如果不可以则将该皇后挪到下一个可行的列"这个过程称之为"状态回溯",即将棋子重新放置,我画了一张图来表示这个过程:
在这里插入图片描述
回溯的过程大致就是这样:不断地去寻找每一行可以放置棋子的位置,放置之后发现不行或者已经达到了4皇后的解,就将其撤回,重新寻找下一种摆放的可能.

2.2 代码解决

一般的回溯算法的模板是这样子的:

private void backtrace(int count) {
        //回溯终止条件
        if (count == xxx) {
           //进行记录处理
            return;
        }

        //回溯过程
        while(xx) {
      			//...
                //继续进行回溯调用
                backtrace(count + 1);
                //状态回溯
                //...
            }
        return;
    }

以下即为任意N皇后问题的解决代码:

    private int res;
    private int N;
    private int[] record;//记录放置的皇后位置
    public int totalNQueens(int n) {
        res = 0;
        N = n;
        record = new int[n];
        backtrace(0, 0);
        return res;
    }

    private void backtrace(int row, int count) {
        //回溯终止条件
        if (count == N) {
            res++;
            return;
        }

        //回溯过程
        //逐行向上放置皇后,可以避免同一行出现皇后,接下来只需要判断每一列的格子是否可以防止皇后
        for (int col = 0; col < N ; col++) {
            if (check(row, col)) {
                System.out.println("在第"+row+"行,第"+col+"列摆放第"+(count+1)+"个皇后");
                //放置皇后在row, col位置
                record[row] = col;
                //继续网上寻找放置皇后的位置
                backtrace(row + 1, count + 1);
                //状态回溯(撤回row, col位置的皇后)
                System.out.println("==撤回第"+row+"行,第"+col+"列的第"+(count+1)+"个皇后");
                record[row] = 0;
            }
        }
        return;
    }

    private boolean check(int row, int col) {
        for (int i = 0; i < row ; i++) {
            //判断列上有没有皇后
            if (record[i] == col) return false;
            //判断斜列上又没有皇后
            if (Math.abs(i - row) == Math.abs(record[i] - col)) return false;
        }
        return true;
    }

执行程序,即可获得4皇后问题的回溯过程和解数量了:

在第0行,第0列摆放第1个皇后
在第1行,第2列摆放第2个皇后
-----撤回第1行,第2列的第2个皇后
在第1行,第3列摆放第2个皇后
在第2行,第1列摆放第3个皇后
-----撤回第2行,第1列的第3个皇后
-----撤回第1行,第3列的第2个皇后
-----撤回第0行,第0列的第1个皇后
在第0行,第1列摆放第1个皇后
在第1行,第3列摆放第2个皇后
在第2行,第0列摆放第3个皇后
在第3行,第2列摆放第4个皇后
-----撤回第3行,第2列的第4个皇后
-----撤回第2行,第0列的第3个皇后
-----撤回第1行,第3列的第2个皇后
-----撤回第0行,第1列的第1个皇后
在第0行,第2列摆放第1个皇后
在第1行,第0列摆放第2个皇后
在第2行,第3列摆放第3个皇后
在第3行,第1列摆放第4个皇后
-----撤回第3行,第1列的第4个皇后
-----撤回第2行,第3列的第3个皇后
-----撤回第1行,第0列的第2个皇后
-----撤回第0行,第2列的第1个皇后
在第0行,第3列摆放第1个皇后
在第1行,第0列摆放第2个皇后
在第2行,第2列摆放第3个皇后
-----撤回第2行,第2列的第3个皇后
-----撤回第1行,第0列的第2个皇后
在第1行,第1列摆放第2个皇后
-----撤回第1行,第1列的第2个皇后
-----撤回第0行,第3列的第1个皇后
故一共有2个解

回溯 ——八皇后问题 八皇后问题: 在8*8的棋盘上,放置8个皇后,使两两之间互不攻击。满足: 1).不在同一列 2).不在同一行 3).不在同一对角线 回溯算法: 确定了解空间的组织结构后,回溯法从开始结点(根结点)出发,以深度优先的方式搜索整个解空间。这个开始结点就成为一个活结点,同时也成为当前的扩展结点。在当前的扩展结点处,搜索向纵深方向移至一个新结点。这个新结点就成... 阅读详情

相关推荐

回溯法解八皇后问题及再看八皇后问题优化

1、介绍 先上张图来说明用回溯法解八皇后问题的每一步:          2、程序 看着严蔚敏的书写的,写好后运行一次性成功了,程序如下: // N皇后问题 #include using namespace std; #define N 8 bool matrix[N + 1][N + 1] = {0}; boo

Tham 在思索中前行! 4268

回溯算法(Backtracking Algorithm)之八皇后问题

文章目录1. 回溯算法思想2. 算法应用2.1 八皇后问题 1. 回溯算法思想 前面讲过贪心算法并不能保证得到最优解,那怎么得到最优解呢? 回溯思想,有点类似枚举搜索。枚举所有的解,找到满足期望的解。 为了有规律地枚举所有可能的解,避免遗漏和重复,把问题求解的过程分为多个阶段。 每个阶段,我们都会面对一个岔路口,我们先随意选一条路走,当发现这条路走不通的时候(不符合期望的解),就回退到上一个岔路...

Michael是个半路程序员 3065

递归之八皇后问题(回溯算法)

八皇后问题 递归 回溯算法 java实现八皇后问题 递归解决八皇后问题 java回溯算法

Ronz 的博客 704

回溯算法——>8皇后问题

一、算法的描述 回溯算法实际是一个类似枚举的搜索尝试方法,它的主题思想是在搜索尝试中找问题的解,当不满足求解条件就”回溯”返回,尝试别的路径。回溯算法是尝试搜索算法中最为基本的一种算法,其采用了一种“走不通就掉头”的思想,作为其控制结构。 二、算法的设计思想 回溯法是在包含问题的所有解的解空间树中。按照深度优先的策略,从根结点出发搜索解空间树,算法搜索至解空间树的任一结点时,总是先判断该结点是否满...

yo_u_niverse的博客 559

[回溯法]从蛮力算法起步,谈八皇后问题的求解:

[回溯法]从蛮力算法起步,谈八皇后问题的求解:                                                                                                                By EmilMatthew                                                   

4463

Python方块圣诞树(完整代码)

Python绘制方块圣诞树的完整代码。

AIGC 712

人工智能课程设计——八皇后问题的求解算法比较

人工智能课程设计——八皇后问题的求解算法比较八皇后问题的求解算法及步骤分析回溯法——通用的解法回溯法求解八皇后问题具体步骤为:爬山法——经典的解法随机重启爬山法——前进的解法模拟退火法——他山之石A* 算法——启发式解法参考文献 最近暑假有些空闲时间,于是把这学期写的一些课程设计记录下来,如果有需要请自取,原创不易,希望能给各位的学习带来一些方便。 八皇后问题的求解算法及步骤分析 回溯法——通用的...

qq_33215171的博客 4778

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

前言 说起八皇后问题,它是一道回溯算法类的经典问题,也可能是我们大部分人在上数据结构或者算法课上遇到过的最难的一道题…… 第一次遇到它的时候应该是大一下或者大二这个期间,这个时间对啥都懵懵懂懂,啥都想学却发现好像啥都挺难的,八皇后同样把那个时候的我阻拦在外,我记得很清楚当时大二初我们学业导师给我们开班会时候讲到的一句话很清晰:“如果没有认真的学习算法他怎么可能解出八皇后的代码呢”。 确实,那个时候的我搞不懂递归,回溯也没听过,连Java的集合都没用明白,毫无逻辑可言,八皇后对我来说确实就是无从下手。 但今

bigsai 3504

八皇后问题遗传算法c语言,遗传算法解决八皇后问题

8种机械键盘轴体对比本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?八皇后问题描述19 世纪著名的数学家 Gauss 在 1850 年提出八皇后问题后, 该问题成为各类语言程序设计的经典题目。 八皇后问题要求在 8×8 格的国际象棋上摆放八个皇后,使横、竖、斜方向上都不能有两个及两个以上皇后在同一条直线上, 问题也可以推广到 N 个皇后。 穷举法在问题规模不大的情况下还可适用,回溯法是求...

weixin_31935793的博客 696

NQueensSolution:N比N的皇后问题最古老的基于国际象棋的问题之一是在棋盘上放置8个皇后,而皇后不会互相攻击。 (如果您不熟悉国际象棋,则女王可以攻击同一行上的任何正方形,同一列上的任何正方形或同一对角线上的任何正方形)。 编写代码枚举所有解决方案是一个有趣的小练习。 在本周的挑战中,您的任务是编写代码以显示将n个皇后放在n x n棋盘上的单个解决方案。 请注意,我们只寻找一种解决方案,而不是全部。 用户输入n,输出应该是(x1,y1),(x2,y2),...,(xn,yn)上皇后形式的解,其

N个N个皇后问题 N比N的皇后问题最古老的基于国际象棋的问题之一是在棋盘上放置8个皇后,而皇后不会互相攻击。 (如果您不熟悉国际象棋,则女王可以攻击同一行上的任何正方形,同一列上的任何正方形或同一对角线上的任何正方形)。 编写代码枚举所有解决方案是一个有趣的小练习。 在本周的挑战中,您的任务是编写代码以显示将n个皇后放在n x n棋盘上的单个解决方案。 用户输入n,输出应该是(x1,y1),(x2,y2),...,(xn,yn)上皇后形式的解,其中xi代表行号,yi代表行号列号。 例子: 输入棋盘n的大小,以n为单位:8 输出:(1,1),(7,2),(5,3),(8,4),(2,5),(4,6),(6,7),(3,8)上的皇后区) 请注意,n应在4到25(含)范围内。 #跑步 javac SinqleQueenSolution.java java SinqleQueenSolu

回溯法n后问题实验报告

在n×n格的棋盘上放置彼此不受攻击的n个皇后。按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。n后问题等价于在n×n格的棋盘上放置n个皇后,任何2个皇后不放在同一行或同一列或同一斜线上。

八皇后问题4种c语言算法

八皇后问题 1.递归回溯法 B站懒猫老师讲的(我在这里学的) 八皇后问题的递归回溯算法思路:从第一行开始当某一行皇后位置不与前面所有皇后位置冲突那么记录该行皇后位置并调用递归函数进入下一行,摆放下一个皇后,逐个位置摆放,若该行所有位置都被其他皇后占领,那么就回溯到上一行重新摆放上一行皇后直至所有皇后都不冲突那么记录一次方法然后回溯寻找其他摆放方法。 冲突算法思路:一个8*8的棋盘每一个位置若用其行号加上其列号我们可以得到下图,由图可知在同一条上对角线的数值都相同,因此我们可以利用该规律设计判断上对角线是否冲

yunProgrammer的博客 1万+

Aruba无线控制器实战:如何用Client Match优化企业办公区漫游(附SNR调优技巧)

本文深入解析了如何利用Aruba无线控制器的Client Match功能优化企业办公区无线漫游体验。通过实战配置,详细阐述了基于SNR(信噪比)的精细化调优策略,包括阈值设定、负载均衡与场景化参数调整,旨在解决终端粘滞、乒乓漫游等问题,实现智能、平滑的无缝漫游。

weixin_28318011的博客 230

八皇后问题(回溯法)

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

skill_Carney的博客 1万+

Win10 + Linux 双系统删除(Linux)

删除Linux所使用的磁盘分区 进入此电脑->计算机->管理->磁盘管理

weixin_52247624的博客 944

从VBA到Python:探索CODE V API在MTF数据分析中的跨语言实践

本文详细介绍了如何从VBA转向Python,利用CODE V API实现MTF数据分析的高效工作流。通过Python的科学计算库和现代API设计,光学工程师可以大幅提升数据处理和可视化效率,实现自动化报告生成和性能优化。

weixin_29239661的博客 444

八皇后问题的回溯搜索算法

八皇后问题是一个经典的问题,要求在8×8的国际象棋棋盘上放置8个皇后,使得彼此之间无法互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上。这个问题可以通过回溯搜索算法来解决。回溯搜索算法的基本思想是:在搜索过程中,每次都做出一个选择,然后继续搜索;如果当前选择导致问题无法解决,就回溯到上一个状态,尝试其他选择,直到找到问题的解或者确定无解为止。

Morr0w的博客 893

SMPLify-X关键点映射与OpenPose格式转换实战

本文深入解析了SMPLify-X与OpenPose之间关键点映射与格式转换的实战方法。针对SMPL、SMPL-H、SMPLX等参数化人体模型与OpenPose 2D姿态估计标准之间的数据鸿沟,文章详细对比了双方的关键点定义差异,并提供了核心的Python转换代码与映射表构建思路。通过清晰的步骤讲解与调试技巧,帮助开发者实现3D关节数据到OpenPose标准格式的高效、准确转换,为动作捕捉、3D姿态估计等应用奠定数据基础。

weixin_29046035的博客 166

八皇后问题:回溯算法精解

八皇后问题是一个经典的组合优化问题,最早由国际象棋棋手马克斯・贝瑟尔(Max Bezzel)于 1848 年提出。问题要求在 8×8 的国际象棋棋盘上放置 8 个皇后,使得任意两个皇后都不能互相攻击,即任意两个皇后不能处于同一行、同一列或同一对角线上。行约束:每一行只能放置一个皇后列约束:每一列只能放置一个皇后对角线约束:分为正对角线(从左上到右下)和反对角线(从右上到左下),任意两个皇后不能处于同一条对角线上。

2501_94572641的博客 905

C# HttpClient 实战:3步绕过Cloudflare指纹拦截,获取完整网页内容

本文详细介绍了如何使用C# HttpClient绕过Cloudflare指纹拦截,获取完整网页内容的3步实战方案。通过完美复制浏览器请求头、智能管理Cookie容器以及处理动态挑战页面,开发者可以有效突破Cloudflare的反爬机制,适用于爬虫开发和数据采集项目。

weixin_31856057的博客 323

从静态到动态:如何用Deformable 3DGS和4DGS实现高效动态场景建模

本文深入探讨了Deformable 3DGS和4DGS在动态场景建模中的技术突破,详细解析了这两种方法如何高效处理动态内容。Deformable 3DGS通过引入时间维度的变形场扩展传统3DGS,而4DGS则采用四维时空体素分解方法,两者均显著提升了动态场景建模的效率和质量,适用于虚拟现实、增强现实等应用场景。

weixin_29063035的博客 435

八皇后时间复杂度_回溯算法 | 追忆那些年曾难倒我们的八皇后问题

文章收录在公众号:bigsai,关注更多干货和学习资源记得点赞、在看前言说起八皇后问题,它是一道回溯算法类的经典问题,也可能是我们大部分人在上数据结构或者算法课上遇到过的最难的一道题……在这里插入图片描述第一次遇到它的时候应该是大一下或者大二这个期间,这个时间对啥都懵懵懂懂,啥都想学却发现好像啥都挺难的,八皇后同样把那个时候的我阻拦在外,我记得很清楚当时大二初我们学业导师给我们开班会时候...

weixin_39688170的博客 3313

撸毛笔记-电信营业厅 v5.03

电信营业厅 v5.03签到和完成部分金豆任务, 喂宠物7天,15天,28天连签抽奖, 宠物等级权益兑换自己设置电信的服务密码, 把 手机号#服务密码 填到变量里:每天运行一两次const $ = new Env("电信营业厅");

xiaoshun007的专栏 4500

从八皇后问题剖析回溯算法

首先让我们来看一下什么是八皇后问题 在8*8的棋盘上放置8个皇后而彼此不受攻击(即在棋盘的任一行,任一列和任一对角线上不能放置2个皇后) 这道题运用回溯算法,那么什么是回溯算法? 简单来说,就是先按照一种方法向前试探,当发现这种方法不是最优解或者不能到达目标时,退回一步,换下一种方法继续试探,知道找到终点为止 其实回溯算法都有一个很相似的套路 void go(int k) { for(i...

qpfxgg的博客 413

论文阅读:Universal and Transferable Adversarial Attacks on Aligned Language Models. LLM Attacks

因为“即开即用”的大型语言模型能够生成大量令人反感的内容,近期的工作集中在对这些模型进行对齐,以防止不受欢迎的生成。尽管在规避这些措施方面取得了一些成功——即所谓的针对大型语言模型(LLMs)的“越狱”——这些攻击需要大量的人类智慧,并且在实践中很脆弱。自动对抗性提示生成的尝试也取得了有限的成功。在本文中,我们提出了一种简单有效的攻击方法,可以导致对齐的语言模型生成令人反感的行为。

CSPhD-winston的博客 1419

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

回溯算法及典型例题

大多是使用回溯算法的题目都符合以下条件: 输出可以看作一个n元组(x1,x2,…,xn),例如八皇后问题。 元组需要满足一些约束条件。 个人认为回溯算法和暴力法有很大的相似度,但是回溯算法会在每次构造解的过程中进行剪枝。整个选择过程可以构成一棵状态空间树,树的根可以代表查找解之前的初始状态。大多数情况下可以用DFS的方法来生成状态空间树。如果当前结点是有希望的,可以继续深度遍历,否则回溯到父母节点。 首先来看一道经典例题 一.八皇后问题 1.问题描述 在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击

qq_43406565的博客 4739

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

上一篇: LeetCode(7)-树:DFS/BFS类问题
下一篇: Java基础(6)-ArrayList和LinkedList一览
BoringRong
BoringRong 领域专家: 后端开发技术领域 领域专家: 后端开发技术领域
博客等级 码龄9年 2万+粉丝 386原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BoringRong

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值