回溯法求解八皇后问题

这篇具有很好参考价值的文章主要介绍了回溯法求解八皇后问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

问题提出:八皇后问题是一个古老而著名的问题。该问题是十九世纪著名的数学家高斯1850 提出在 8x8 格的国际象棋上摆放八皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了 40 种不同的解,后人有人用图论的方法解出 92种结果。虽然问题的关键在于如何判定某个皇后所在的行、列、斜线是否有别的皇后;可以从矩阵的特点上找到规律,如果在同一行,则行号相同:如果在同一列上,则列号相同;如果同在“/”斜线上的行列值之和相同:如果在对角线上,则行列号之和或行列号之差相等,逐个纪录符合题意的情况,最终得出解。

解决思路:利用数组来求解。

1)解决冲突问题:这个问题包括了行,列,两条对角线。

行:规定每一行放一个皇后,不会造成行上的冲突;

列:当第1列被某个皇后占领后,则同一列上的所有空格都不能再放皇后,被标记位置为被占领状态。

对角线:对角线有两个方向,在同一对角线上的所有点都不能有冲突。

2)使用算法分析与设计的知识,用递归法、枚举法、回溯法等解决问题。

3)思考要解决的问题:用什么算法分析与设计来描述棋盘,怎样描述棋盘,怎样描述皇后(包括皇后的位置,怎样移动皇后等)。怎样开始程序。

4)初步解决问题,列出大纲。

所用算法

回溯法:

回溯算法也叫试探法,它是一种系统地搜索问题的解的方法。按选优条件向

前搜索,以达到目标。当探索到某一步时,发现原先选择并不优或达不到目标, 就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。

行A的皇后放在第一列以后,行B的皇后放在第一列已经发生冲突。这时候不必继续放行C的皇后,而是调整行B的皇后到第二列,继续冲突放第三列,不冲突了才开始进入行C。如此可依次放下行A至E的皇后,将每个皇后往右边横向、斜向攻击的点位用叉标记,发现行F的皇后无处安身。这时回溯到行E的皇后,将其位置由第4列调整为第8列,进入行F,发现皇后依然无处安身,再次回溯行E。此时行E已经枚举完所有情况,回溯至行D,将其由第2列移至第7列,再进入行E继续。按此算法流程最终找到可行解,成功在棋盘里放下了8个“和平共处”的皇后。继续找完全部的解共92个。

回溯算法求解八皇后问题的原则是:有冲突解决冲突,没有冲突往前走,无路可走往回退,走到最后是答案。

流程图:

回溯法求解八皇后问题

 

运行代码:

#include <stdio.h>

int queen[8] = {0};

int sum = 0;

int cnt ; //表示摆放了几个皇后,也表示摆放皇后的行数。

int col ; //表示在这一列上摆放了皇后

void greedy(){

while(1){

//在(cnt,col)这个坐标摆放皇后

if(cnt == 1 && queen[0] == 7 && col == 6){ //表示第一行的皇后已经到了第八列且第二行的皇后到了第六列位置,已经摆放不下皇后了就退出循环

break;

}

int isAttack = 0; //用来表示皇后们之间是否能够攻击的到,如果攻击的到就是1,否则就为0

int i=0;

for(i=0;i<cnt;i++){

if(queen[i] == col){ //表示在同一列上

isAttack = 1;

}

int div_row =cnt -i; //表示斜线上的纵坐标之差

int div_col = queen[i]-col; //表示斜线上横坐标之差

if(div_row == div_col ||div_row == -div_col){ //表示在同一斜线上

isAttack = 1;

}

}

if(isAttack == 0){ //表示可以放置

queen[cnt] = col; //记录皇后当前的列数

cnt++; //开始摆放下一个皇后

col = 0; //下一个皇后从第一列开始遍历

if(cnt == 8){ //如果摆满了八个皇后就打印出他们的摆法

for (i = 0 ; i <= 7; ++i) //打印该种摆放方法情况

{

for (int col=0;col<=7;col++)

{

if (col!=queen[i])

{   

printf("0|");

   }

else{printf("1|");}

}

printf("\n");

}

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

printf("%d  ",queen[i]+1);

}

printf("\n");

sum++;

printf("这是第%d种摆法\n",sum);

printf("\n"); //并且摆放种数+1

do{ //越界问题 //回朔

cnt--; //撤回正在摆放的皇后

col = queen[cnt]+1; //往下一个列寻找摆放位置

}while(col>=8);

}

}else{ //表示不能摆放

col++;

while(col>=8){ //回朔

cnt--; //退一格

col = queen[cnt]+1; //上一个皇后往后移一格

}

}

}

printf("总共有%d种摆法\n",sum);

return ;

}

int main(){

greedy();

return 0;

}

总结感悟:

1.心得体会

这次课程设计我们解决了八皇后问题的位置输出问题,利用回溯法完成了八皇后九十二种解法。本问题的解题思路使用的是典型的回溯算法。回溯法有“通用解题法”之称。用它可以系统地搜索一个问题的所有解或任一解。回溯法在问题的解空间树中,拨深度优先策略,从根节点出发搜索解空间树。算法搜索至解空间树的任一结点时,先判断该结点是否包含问题的解。如果肯定不包含,则跳过对以该结点为根的子树的搜索,逐层向其祖先结点回溯。否则,进入该子树,继续按深度优先策略搜索。它适合于解组合数较大的问题。

2.总结

此次的八皇后课程设计编程过程中,我们从最开始的查资料、确定算法、翻找课件、寻求递归过程一系列流程中,我们小组三人都熟悉掌握了算法设计与分析课程中的回溯、递归的应用,协同完善了八皇后安置问题。通过团队合作,使我们更好的解决问题,每个人都负责不同模块的操作,大大提高了效率。另外网络资料、向他人寻求帮助那些自己掌握不是很深刻的知识点都得到了巩固,大大提高了效率,更是明白了不同算法带来的效果是大大不同的,通过分析推敲我们选择了回溯算法,这种思维更有助于我们解决其他的问题!文章来源地址https://www.toymoban.com/news/detail-401995.html

到了这里,关于回溯法求解八皇后问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • python中级篇1:n皇后问题(回溯算法)

    hello!大家好,我是浪矢秀一。最近经历了许多事情,终于是恢复1次更新了。那么今天呢,我们来学习中级篇,需要学过不少python知识的人来学习。好了,废话不多说,我们进入今天的课程!   在1个n*n的国际象棋棋盘上,放置n个皇后,要求:同1行、同1列、同1斜线上只能有1个皇后。   既然

    2024年02月03日
    浏览(37)
  • 算法:回溯算法(以解决n皇后问题为例)

    基本思想:回溯算法的基本思想是:从一条路往前走,能进则进,不能进则退回来,换一条路再试。八皇后问题就是回溯算法的典型,第一步按照顺序放一个皇后,然后第二步符合要求放第2个皇后,如果没有位置符合要求,那么就要改变第一个皇后的位置,重新放第2个皇后

    2024年02月05日
    浏览(32)
  • 算法与数据结构——递归算法+回溯算法——八皇后问题

    八皇后问题是一个经典的回溯算法问题,目的是在8×8的国际象棋棋盘上放置八个皇后,使得没有皇后可以互相攻击(即没有两个皇后在同一行、同一列或同一对角线上)。 回溯算法是一种解决问题的算法,它通过尝试所有可能的解决方案来解决问题。在八皇后问题中,计算

    2024年02月09日
    浏览(54)
  • 八皇后问题,秒懂递归回溯(有图详解|c语言)

    目录 👸🏻前言 👸🏻题目介绍 👸🏻引入: 👸🏻解决思路: 👸🏻理论存在,实践开始! 👸🏻难点1:如何表示对角线被占领? 👸🏻难点2:如何用递归的方法来放皇后? 👸🏻难点3:如何实现回溯? 👸🏻难点4:如何实现皇后位置的输出? 👸🏻全部代码如下: 👸

    2024年02月02日
    浏览(32)
  • N皇后问题详解:回溯算法的应用与实践(dfs)

    题目如上图所示,在一个 n*n 的国际象棋棋盘上怎么摆放能使得皇后互相攻击不到(也就是在 任意一列、一行、一条对角线上都不存在两个皇后 ) 1.DFS 想要解决这个问题,我们可以使用dfs也就是 深度优先遍历 ,深度优先搜索的步骤为先递归到底再回溯上来,顾名思义,df

    2024年03月26日
    浏览(52)
  • 递归求解n皇后问题的解析和求解(矩阵储存版)

    1. n皇后问题问题描述 ​ n皇后问题来源于著名的十九世纪著名数学家提出的八皇后问题。问题为:在8×8的棋盘上摆放八个皇后,皇后之间不能互相攻击,既任意两个皇后不在同一行、同一列,也不再同一斜线上。n皇后则是在八皇后的基础上,将棋盘扩充为n×n,皇后的数量也

    2024年01月19日
    浏览(36)
  • 回溯法——求解子集和问题(Java)

    给定n个不同的正整数的集合w={w1,w2,…,wn}和一个正整数W,要求找出w的子集s, 使该子集中所有的元素的和为W 。例如,当n=4时,w={11,13,24,7},W=31,则满足要求的子集为(11,13,7)和(24,7)。 和0/1背包问题一样,该问题的解空间数是一颗子集树。设解向量x=(x1,

    2024年02月06日
    浏览(48)
  • 基于回溯法求解0-1背包问题

    一、实验目的 1.掌握基于回溯的算法求解0-1背包问题的原理。 2.掌握编写回溯法求解0-1背包问题函数的具体步骤并理解回溯法的核心思想以及其求解过程。 3.掌握子集树以及其他几种解空间树的回溯方法并具备运用回溯算法的思想设计算法并用于求解其他实际应用问题的能力

    2024年02月08日
    浏览(46)
  • 基于回溯法求解旅行售货员问题

    一、实验目的 1.掌握基于回溯的算法求解旅行商问题的原理。 2.掌握编写回溯法求解旅行商问题函数的具体步骤并理解回溯法的核心思想以及其求解过程。 3.掌握子集树以及其他几种解空间树的回溯方法并具备运用回溯算法的思想设计算法并用于求解其他实际应用问题的能力

    2024年02月09日
    浏览(40)
  • 回溯法,分支限界法,动态规划法求解0-1背包问题(c++)

    问题描述 给定n种物品和一背包。物品i的重量是wi0,其价值为vi0,背包的容量为c。问应如何选择装入背包中的物品,使得装入背包中物品的总价值最大? 搜索空间: 子集树(完全二叉树) 约束函数(进包用): 如果当前背包中的物品总重量是cw,前面k-1件物品都已经决定是否进包,那

    2024年02月10日
    浏览(57)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包