关于N皇后问题高效试探回溯算法的分析

算法:回溯算法(以解决n皇后问题为例) 基本思想:回溯算法的基本思想是:从一条路往前走,能进则进,不能进则退回来,换一条路再试。八皇后问题就是回溯算法的典型,第一步按照顺序放一个皇后,然后第二步符合要求放第2个皇后,如果没有位置符合要求,那么就要改变第一个皇后的位置,重新放第2个皇后的位置,直到找到符合条件的位置就可以了。是一种以深度优先搜索带以跳跃性搜索的算法。 回溯算法说白了就是穷举法,只不过在进行穷举的过程中,用剪枝函数跳过了一些不必要的搜索,跳过了一些不可能到达最终状态的子节点,减少状态空间树节点的生成 那么我们进行回溯算法比较疑惑的 阅读详情

// N Queens Problem
// 试探-回溯算法,递归实现

// sum用来记录皇后放置成功的不同布局数;upperlim用来标记所有列都已经放置好了皇后。
long sum = 0, upperlim = 1;     

// 试探算法从最右边的列开始。
void test(long row, long ld, long rd) 。
{
   if (row != upperlim)
   {
     // row,ld,rd进行“或”运算,求得所有可以放置皇后的列,对应位为0,
     // 然后再取反后“与”上全1的数,来求得当前所有可以放置皇后的位置,对应列改为1。
     // 也就是求取当前哪些列可以放置皇后。
     long pos = upperlim & ~(row | ld | rd); 
     while (pos) // 0 -- 皇后没有地方可放,回溯。
     {
        // 拷贝pos最右边为1的bit,其余bit置0。
        // 也就是取得可以放皇后的最右边的列。
        long p = pos & -pos;                                              

        // 将pos最右边为1的bit清零。
        // 也就是为获取下一次的最右可用列使用做准备,
        // 程序将来会回溯到这个位置继续试探。
        pos -= p;                           

        // row + p,将当前列置1,表示记录这次皇后放置的列。
        // (ld + p) << 1,标记当前皇后左边相邻的列不允许下一个皇后放置。
        // (ld + p) >> 1,标记当前皇后右边相邻的列不允许下一个皇后放置。
        // 此处的移位操作实际上是记录对角线上的限制,只是因为问题都化归
        // 到一行网格上来解决,所以表示为列的限制就可以了。显然,随着移位
        // 在每次选择列之前进行,原来N×N网格中某个已放置的皇后针对其对角线
        // 上产生的限制都被记录下来了。
        test(row + p, (ld + p) << 1, (rd + p) >> 1);                              
       }
   }
   else   
   {
       // row的所有位都为1,即找到了一个成功的布局,回溯。
       sum++;
   }
}

int main(int argc, char *argv[])
{
   time_t tm;
   int n = 16;

   if (argc != 1)
   n = atoi(argv[1]);
   tm = time(0);

   // 因为整型数的限制,最大只能32位,
   // 如果想处理N大于32的皇后问题,需要
   // 用bitset数据结构进行存储。
   if ((n < 1) || (n > 32))                 
   {
   printf(" 只能计算1-32之间/n");
   exit(-1);
   }
   printf("%d 皇后/n", n);

   // N个皇后只需N位存储,N列中某列有皇后则对应bit置1。
   upperlim = (upperlim << n) - 1;         

   test(0, 0, 0);
   printf("共有%ld种排列, 计算时间%d秒 /n", sum, (int) (time(0) - tm));
}

上述代码容易看懂,但我觉得核心的是在针对试探-回溯算法所用的数据结构的设计上。
程序采用了递归,也就是借用了编译系统提供的自动回溯功能。

算法的核心:使用bit数组来代替以前由int或者bool数组来存储当前格子被占用或者说可用信息,从这

可以看出N个皇后对应需要N位表示。
巧妙之处在于:以前我们需要在一个N*N正方形的网格中挪动皇后来进行试探回溯,每走一步都要观察

和记录一个格子前后左右对角线上格子的信息;采用bit位进行信息存储的话,就可以只在一行格子也

就是(1行×N列)个格子中进行试探回溯即可,对角线上的限制被化归为列上的限制。
程序中主要需要下面三个bit数组,每位对应网格的一列,在C中就是取一个整形数的某部分连续位即可

。
row用来记录当前哪些列上的位置不可用,也就是哪些列被皇后占用,对应为1。
ld,rd同样也是记录当前哪些列位置不可用,但是不表示被皇后占用,而是表示会被已有皇后在对角线

上吃掉的位置。这三个位数组进行“或”操作后就是表示当前还有哪些位置可以放置新的皇后,对应0

的位置可放新的皇后。如下图所示的8皇后问题求解得第一步:
row:          [ ][ ][ ][ ][ ][ ][ ][*]
ld:           [ ][ ][ ][ ][ ][ ][*][ ]
rd:           [ ][ ][ ][ ][ ][ ][ ][ ]
--------------------------------------
row|ld|rd:    [ ][ ][ ][ ][ ][ ][*][*]
所有下一个位置的试探过程都是通过位操作来实现的,这是借用了C语言的好处,详见代码注释。

关于此算法,如果考虑N×N棋盘的对称性,对于大N来说仍能较大地提升效率!

回溯法求解N皇后问题 本文介绍了回溯法及其在解决N皇后问题中的应用。回溯法是一种通过试探性搜索解决问题的算法,核心思想是“尝试-回退”,通过系统性搜索、剪枝优化和递归实现来高效穷举所有可能解。N皇后问题要求在n*n棋盘上放置n个皇后,使得它们互不攻击。文章详细分析了问题的解题思路,提出了剪枝条件函数,并设计了递归和非递归两种算法来实现回溯法。递归法通过递归调用逐行放置皇后,而非递归法则通过迭代实现。总结指出,回溯法通过智能穷举和剪枝优化,在解决组合问题时能显著减少无效搜索,适用于N皇后、数独、图着色等场景,是解决NP难问题的重要 阅读详情

相关推荐

N皇后问题 (史上最快解法 位运算)

欢迎访问https://blog.youkuaiyun.com/lxt_Lucia~~ 宇宙第一小仙女\(^o^)/~~萌量爆表求带飞=≡Σ((( つ^o^)つ~ dalao们点个关注呗~~ ------------------------------------我只是一条可爱哒分界线-------------------------------------- 今天在论坛上有幸看到了一个难...

lxt_Lucia的博客 5601

算法设计与分析——回溯法——n皇后问题

一、什么是N皇后问题? 在n×n格的棋盘上放置彼此不受攻击的n个皇后。按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。n后问题等价于再n×n的棋盘上放置n个皇后,任何2个皇后不妨在同一行或同一列或同一斜线上。 #include<iostream> using namespace std; class Queen{ public: bool Place(int k); void Backtrack(int t); int n;//皇后的个数 in

qq_50675813的博客 7794

N皇后问题深度解析与回溯算法实战

一个合法状态需同时满足三个约束:列不冲突:使用长度为$ N $的布尔数组标记各列是否被占用;主对角线不冲突:主对角线索引为 $ row - col \in [-(N-1), N-1] $,共 $ 2N - 1 $ 条;副对角线不冲突:副对角线索引为 $ row + col \in [0, 2N - 2] $,同样共 $ 2N - 1 $ 条。以4皇后为例,存在两个有效解:这些解展示了对称性结构和稀疏分布特征,揭示了剪枝搜索的必要性。

weixin_28895791的博客 1166

回溯法(backtracking algorithm)求解N皇后问题(N-Queens puzzle)

转载自:用回溯法(backtracking algorithm)求解N皇后问题(N-Queens puzzle) N皇后问题 八皇后问题,是一个古老而著名的问题.该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法? N皇后问题是一个经典的问题,在一个N*N的棋盘上放置N...

sky的博客 8331

三算法解决n皇后问题:回溯法、遗传算法与CSP最小冲突法

n皇后问题是一个经典的回溯算法问题,其挑战在于在一个n×n的棋盘上放置n个皇后,使得它们互不攻击,即任意两个皇后不能处于同一行、同一列或同一斜线上。随着n的增加,问题的复杂性呈指数增长,这给求解带来了极大的挑战。遗传算法由美国计算机科学家John Holland在1975年首次提出,其灵感来源于达尔文的生物进化理论。GA通过模拟生物进化中的“适者生存、不适者淘汰”的自然选择机制,来进行问题求解。遗传算法的主要组成部分包括:种群(Population)

weixin_28968525的博客 1134

算法分析 N皇后问题

算法分析 N皇后 N皇后问题是算法设计中的一个经典问题,拉斯维加斯算法解决N皇后问题利用了每个皇后放置的随机性,,这种随机性选择常比最优选择省时,因此拉斯维加斯算法解决N皇后问题可在最大程度上降低算法的复杂度。使用回溯法和拉斯维加斯算法相结合的优化策略避免了拉斯维加斯算法中,一旦发现无法再放置下一个皇后就需要全部重新开始的缺点,从而获得了更好的算法执行效率。

【回溯算法】n皇后问题(详解 + 详细代码)

N皇后详解【回溯算法】-java代码

LYJbao的博客 3690

回溯算法实现5皇后问题

回溯实现n后问题,用c语言实现,默认定义皇后个数为五个,可以自己定义,输出排列结果,本程序只是简单的利用回溯法实现五皇后问题,

n皇后问题-回溯法求解

n皇后问题-回溯法求解 1.算法描述 在n×n格的国际象棋上摆放n个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 n皇后是由八皇后问题演变而来的。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 高斯认为有76...

Pan的博客 7万+

用回溯法解决八皇后问题C语言实现

有多种方法解决八皇后问题,在这里我用的是回溯法解决八皇后问题。大家一起来学习呀!!

算法设计与分析 回溯法 n皇后问题

在n*n格的棋盘上放置彼此不受攻击的n个皇后。按照国际向其的规则,皇后可以攻击同一行、同一列、同一斜线上的棋子。

N皇后问题的两个最高效的算法

N皇后问题是一个经典的问题,在一个N*N的棋盘上放置N个皇后,每行一个并使其不能互相攻击(同一行、同一列、同一斜线上的皇后都会自动攻击)。 一、 求解N皇后问题是算法中回溯法应用的一个经典案例        回溯算法也叫试探法,它是一种系统地搜索问题的解的方法。回溯算法的基本

Hackbuteer1的专栏 17万+

AT32F421玩转AM32电调:手把手教你调试过零点比较器,告别电机抖动

本文详细介绍了如何使用AT32F421芯片调试AM32电调的过零点比较器,解决电机抖动问题。通过硬件配置、软件环境搭建、比较器电路原理分析及filter_level参数动态调整等实战步骤,帮助开发者精准诊断和优化电机控制性能。

weixin_42525632的博客 276

一、试探回溯法(N皇后问题)

 一、试探回溯法概念 在介绍试探回溯法的概念之前,先简要介绍一个简短的古希腊神话故事,邪恶的半人半牛藏身于一个复杂的迷宫,很难找到它并杀死它,就是能成功杀死它怎么回来也是个难事。不过,在公主阿里阿德涅的帮助下,英雄忒修斯还是想到办法并消灭了怪物,并轻轻松松地走出了迷宫,他是怎么做到的呢? 其实,忒修斯使用的法宝很简单,就是一团普通的绳,他将绳子的一段系在迷宫的入口上,然后用手拿着另一端进入迷宫...

天涯明月刀的博客 9363

数字IC设计之时序分析基础概念汇总

时序分析主要有两种办法:静态时序分析: (static timing analysis,STA),是遍历电路存在的所有时序路径,根据给定工作条件(PVT)下的时序库.lib文件计算信号在这些路径上的传播延时,检查信号的建立和保持时间是否满足约束要求,根据最大路径延时和最小路径延时找出违背时序约束的错误。

weixin_45230720的博客 5606

海康视觉相机驱动软件MVS参数配置全攻略(附接线图+避坑指南)

本文提供了海康视觉相机驱动软件MVS从硬件连接到软件参数配置的完整指南。详细解析了供电与通讯线缆的区分、PNP/NPN信号逻辑的接线避坑方法,并重点阐述了MVS软件中触发模式、网络IP配置、图像采集及光源控制等核心参数的设置技巧,旨在帮助用户快速完成相机调试,实现稳定高效的图像采集。

weixin_29204205的博客 399

回溯法-排列树-n皇后问题

N皇后问题: 在一个N*N的棋盘上放置N个皇后,每行一个并使其不能互相攻击(同一行、同一列、同一斜线上的皇后都会自动攻击)。思路:首先要确定皇后间位置合法的检验表达式。((abs(i-k)==abs(x[i]-x[k]))||x[i]==x[k]) //x[i]表示i皇后在第x[i]列;abs(i-k)==abs(x[i]-x[k])表示在两皇后在同一对角线上。然后每第i皇后在第i行有n个...

lfbcsdn博客 4181

Verilog实战:手把手教你实现IEEE 754单精度浮点乘法器(附完整代码)

本文详细介绍了如何使用Verilog实现IEEE 754单精度浮点乘法器,包括标准解析、架构设计、Verilog代码实现及优化技巧。通过两级流水线设计,平衡性能与面积,适用于数字信号处理、AI加速器等高性能计算场景。

weixin_33724046的博客 314

N皇后的两个最高效的解法

1. 问题描述 N皇后问题是一个经典的问题,在一个N*N的棋盘上放置N个皇后,每行一个并使其不能互相攻击(同一行、同一列、同一斜线上的皇后都会自动攻击)2. 回溯法求解N皇后 回溯算法也叫试探法,它是一种系统地搜索问题的解的方法。回溯算法的基本思想是:从一条路往前走,能进则进,不能进则退回来,换一条路再试。在现实中,有很多问题往往需要我们把其所有可能穷举出来,然后从中找出满足某种要求的可能或最优

hacker00011000的专栏 1万+

基于分位数回归的静态CoVaR计算 案例与代码

原文链接:https://bbs.pinggu.org/thread-7925441-1-1.html 一、静态CoVaR模型介绍 二、资料简介 实现对相关期刊论文进行论文重现,解决实证分析中的技术操作问题。里面包含了每一步详细的步骤,可以方便的利用这个手册解决大部分利用分位数回归计算静态CoVaR的论文的模型实现问题。即从数据下载到模型实现一整条操作步骤。 关键词:【分位数回归】【Co...

ChenQihome9的博客 7504

3.3 数据导入与导出方法

Simulink 提供了多种数据导入与导出方法,能够满足不同场景下的需求。无论是从 MATLAB 工作区或外部文件导入数据,还是将仿真结果导出到工作区或文件,这些功能都极大地增强了模型的灵活性和实用性。掌握这些方法后,用户可以更高效地完成复杂系统的建模与分析任务。

xiaoheshang_123的博客 318

n皇后问题_递归回溯法

著名n皇后问题 题目为: n个皇后摆放在N x N的棋盘格中,使得横、竖和两个对角线方向均不会同时出现两个皇后。 解题思路: 利用递归的方法依次查找,回溯再查找 找到第一行的第一个合适位置后,进入第二行查找,找到合适位置放置皇后,进入第三行,如果此时第三行无解,则回到第二行,寻找第二个合适位置,如果第二行没有合适位置,则回到第一行寻找下一个可以放置皇后的位置 这就是回溯 如图 图片来自:n皇后...

HURRYMK的博客 1046

封装POD与PinMap文件总结学习-20250516

芯片封装外形图(POD)和PinMap是芯片设计和制造中的关键文档。POD详细描述了芯片的物理尺寸、引脚布局和封装类型,而PinMap则提供了芯片封装上各个引脚的位置、名称和功能的详细信息。这些文档在芯片设计、制造和应用过程中起到“地图”的作用,帮助设计人员理解芯片的物理和电气特性。在PCB设计中,POD用于确定socket的footprint和pogo的选型,而PinMap则用于器件的合理布局和布线。这些信息对于确保芯片的正确安装和功能至关重要。

歌颂苦难的行为是无耻的; 2369
上一篇: 如何使用迭代器iterator循环删除容器中的元素?
下一篇: C++成员函数指针的应用
sharpdew
博客等级 码龄23年 76粉丝 35原创
评论 6
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值