AI -- 回溯法解决四皇后问题

AI -- 回溯法解决四皇后问题

回溯法

四皇后

C语言


问题描述

在 4*4 的棋盘上无冲突的摆放 4 个皇后,无冲突是指一个皇后所在位置的水平、竖直以及斜线上不能出现其他的皇后,其他的 n 皇后问题以此类推

解决方法

按行来摆放棋子,下一行的摆放满足于与上一行的棋子没有冲突,否则就返回上一步走其他的路线,这就是所谓的回溯法

详细说明

  1. 在第一行有四种可能,选择第一个位置放上皇后

  2. 第二行原本可以有四种可能摆放,但是第一第二个已经和第一行的皇后冲突了,因此只剩下第三第四个格子了,先选择第三个格子

  3. 接下来是第三行,根据规则可以看出,第三行已经没有位置放了,因为都跟第一第二行的皇后冲突,此时返回到第二行第四个

  4. 继续来到第三行,发现只有第二个满足条件

  5. 然后发现第四行已经不能放了,只能继续返回,返回到第一行,开始下一种可能

  6. 按照 1-5 的步骤,可以找到下面的其中一种解法

总而言之,回溯法就是开始一路到底,碰到南墙了就返回走另外一条路,有点像穷举法那样走遍所有的路

算法实现

构建二维数组,增加规则,利用递归实现回溯效果

# include <stdio.h>
# define N 4         // 可以调整

int count=0;

// 判断 Q[i][j] 是否存在冲突
int isCorrect(int i, int j, int (*Q)[N]) {

    int s,t;
    // 判断行
    for(s=i,t=0; t<N; t++)
        if(Q[s][t]==1 && t!=j)
            return 0;

    // 判断列
    for(s=0,t=j; s<N; s++)
        if(Q[s][t]==1 && s!=i)
            return 0;

    // 判断左上角
    for(s=i-1,t=j-1; s>=0&&t>=0; s--,t--)
        if(Q[s][t]==1)
            return 0;

    // 右下角
    for(s=i+1,t=j+1; s<N&&t<N; s++,t++)
        if(Q[s][t]==1)
            return 0;

    // 右上角
    for(s=i-1,t=j+1; s>=0&&t<N; s--,t++)
        if(Q[s][t]==1)
            return 0;

    // 左下角
    for(s=i+1,t=j-1; s<N&&t>=0; s++,t--)
        if(Q[s][t]==1)
            return 0;

    return 1;

}

// 递归函数,第 i+1 行的遍历
void Queue(int i, int (*Q)[N]) {

     int j,k;

     // 第四行已经遍历完,打印符合条件的结果,结束
     if(i==N) {

         count++;
         printf("No.%d slove way\n",count);
         for(k=0;k<N; k++) {

             for(j=0; j<N; j++)
                 printf("%-5d", Q[k][j]);
             printf("\n");

             //return;
         }
         printf("\n");

     }

     // 遍历第 i+1 行的 j+1 列
     for(j=0;j<N; j++) {

         if(isCorrect(i,j,Q)) {

             Q[i][j]=1;
             Queue(i+1,Q);   // 遍历下一行
             Q[i][j]=0;      // 如果下一行不成立,则回溯,重置 0                      

         }
     }
}

int main() {

    int Q[N][N];
    int i,j;

    // 初始化二维数组并打印
    for (i=0; i<N; i++) { 

        for(j=0; j<N; j++) {
            Q[i][j] = 0;
            printf("%-5d",Q[i][j]);
        }
        printf("\n");

    }
    printf("\n");
    Queue(0, Q); // 从第一行开始递归
    printf("solve count is %d\n", count);
    getchar();
    getchar();
    return 0; 

}

效果展示

N = 4 时,有两种解法

两种解法

N = 8 时,有 92 种解法

92 种解法

然后手贱试了一下 N = 16 的,结果跑了 7-8 分钟这样,已经到了第23028 种解法了,第一行还在第一个位置,果断放弃

enter description here

时间: 2024-10-22 16:58:37

AI -- 回溯法解决四皇后问题的相关文章

回溯法解决四皇后问题

以4皇后为例,其他的N皇后问题以此类推.所谓4皇后问题就是求解如何在4×4的棋盘上无冲突的摆放4个皇后棋子.在国际象棋中,皇后的移动方式为横竖交叉的,因此在任意一个皇后所在位置的水平.竖直.以及45度斜线上都不能出现皇后的棋子,例子 要求编程求出符合要求的情况的个数.四皇后问题有很多种解法,这里主要介绍一种经典的解决方法:回溯法 回溯法的基本思想是:可以构建出一棵解空间树,通过探索这棵解空间树,可以得到四皇后问题的一种或几种解.这样的解空间树有四棵 在如上图所示的4×4的棋盘上,按列来摆放棋子,

华为机试—N皇后问题(高级题160分:两种回溯法解决 吐血整理)

一.问题描述: 在n×n格的棋盘上放置彼此不受攻击的n个皇后.按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子.n后问题等价于再n×n的棋盘上放置n个皇后,任何2个皇后不妨在同一行或同一列或同一斜线上. 输入: 给定棋盘的大小n (n ≤ 13) 输出: 输出有多少种放置方法. 二.解题思路: 要解决N皇后问题,其实就是要解决好怎么放置这n个皇后,每一个皇后与前面的所有皇后不能在同一行.同一列.同一对角线,在这里我们可以以行优先,就是说皇后的行号按顺序递增,只考虑第i个皇

回溯法解决迷宫问题

现在有迷宫地图:(回溯法) 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 0 1 1 1 1 0 1 1 1 1 0 1 1 1 1 0 1 1 1 1 0 1 1 1 1 1 1 1 将迷宫地图存于文件中,将文件里的信息依次读入到二维数组中,设置入口,先将

回溯法解决八皇后问题

八皇后问题是学习回溯算法时不得不提的一个问题,用回溯算法解决该问题逻辑比较简单. 下面用java版的回溯算法来解决八皇后问题. 八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例.该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行.同一列或同一斜线上,问有多少种摆法. 思路是按行来规定皇后,第一行放第一个皇后,第二行放第二个,然后通过遍历所有列,来判断下一个皇后能否放在该列.直到所有皇后都放完,或者放哪

用试探回溯法解决N皇后问题

学校数据结构的课程实验之一. 数据结构:(其实只用了一个二维数组) 算法:深度优先搜索,试探回溯 需求分析: 设计一个在控制台窗口运行的“n皇后问题”解决方案生成器,要求实现以下功能: 由n*n个方块排成n行n列的正方形称为n元棋盘.如果两个皇后位于n元棋盘上的同一行.同一列或同一对角线上,则称它们在互相攻击.现要找出使棋盘上n个皇后互不攻击的布局. 编制程序解决上述问题,以n=6运行程序,输出结果. 算法解释: 首先试探当前行第一个可用的位置(列.对角线没有被占领),摆放皇后之后,试探下一行的

八皇后之回溯法解决[转]

问题描述: 要在8*8的国际象棋棋盘中放8个皇后,使任意两个皇后都不能互相吃掉.规则是皇后能吃掉同一行.同一列.同一对角线的棋子.如下图即是两种方案: . 解决方案: 8*8的棋盘要摆放8个皇后,且不能同行同列同对角线,那么每行必定会有一个皇后.我们可以设一个数组a用来存放每一行皇后的位置,元素值表示第几列(如a[1]=5表示第一行的皇后处于第五个格).然后只需要求出数组a的值 问题就解决了,下面介绍三种回溯解法: 1.八个for循环.用枚举的办法,八个for循环分别枚举每一行的8个位置,但是我

回溯法解决八皇问题

把八个皇后放在一个8*8的棋盘上面,要求同一行.同一列.同一对角线不能有两个皇后. 思路:关键在于判定两个皇后是否在同一行.同一列或同一对角线上.这里,棋盘下标从1开始算起.观察发现:若是在同一行,则行号相同:若在同一列,则列号相同:若在同一“/”对角线,则行列值之和相同:若是在同一“\”对角线,则行列值之差相同.考虑到每行仅有一个皇后,设一维数组a[1...8]表示皇后的位置:第i行第j列放置皇后,则a[i]=j,即下标是行数,值是列数.判断皇后是否安全,即检查同一列.同一对角线是否已经有皇后

回溯法解决N皇后问题

以4皇后为例,其他的N皇后问题以此类推.所谓4皇后问题就是求解如何在4×4的棋盘上无冲突的摆放4个皇后棋子.在国际象棋中,皇后的移动方式为横竖交叉的,因此在任意一个皇后所在位置的水平.竖直.以及45度斜线上都不能出现皇后的棋子     1   1             1   1    

回溯法——n后问题

问题描述: 在n*n的棋盘上放置彼此不受攻击的n个皇后.按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子.n后问题等价于在n*n格的棋盘上放置n个皇后,任何2个皇后不放在同一行或同一列或同一斜线. 盲目的迭代枚举: 1 /* 2 *作者:xymaqingxiang 3 *说明:八皇后--盲目迭代法 4 *分析:通过8重循环模拟搜索空间中的8^8个状态,从中找出满足约束条件的可行性方案 5 *日期:2014-05-15 6 */ 7 #include <iostream>