人工智能报告:经典回溯问题——八皇后问题

写在报告前:
八皇后是经典的回溯问题,也是人工智能的入门级题目,在保证功能的前提下我尽量缩减了代码量,也在原有报告代码添加注释以方便大家快速掌握。
一.作业任务
八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
二.运行环境
Windows10,codeblocks。
三.算法介绍
八皇后算法是典型的回溯算法问题。回溯算法实际上一个类似枚举的搜索尝试过程,主要是在搜索尝试过程中寻找问题的解,当发现已不满足求解条件时,就“回溯”返回,尝试别的路径。回溯算法也叫试探法,它是一种系统地搜索问题的解的方法。用回溯算法解决问题的一般步骤:
1、 针对所给问题,定义问题的解空间,它至少包含问题的一个(最优)解。
2 、确定易于搜索的解空间结构,使得能用回溯法方便地搜索整个解空间 。
3 、以深度优先的方式搜索解空间,并且在搜索过程中用剪枝函数避免无效搜索。
第一步按照顺序放一个皇后,然后第二步符合要求放第2个皇后,如果没有位置符合要求,那么就要改变第一个皇后的位置,重新放第2个皇后的位置,直到找到符合条件的位置就可以了。回溯算法使用剪枝函数,剪去一些不可能到达最终状态(即答案状态)的节点,从而减少状态空间树节点的生成。
四.程序分析
程序使用的语言为c++,本代码将棋盘信息保存在c[20]中,通过全局变量n来设定皇后数量,使用search函数进行求解并用print函数打印所有可能的棋盘情况。
五.界面截图
1、八皇后问题:

在这里插入图片描述
此图片中黑白方格代表无棋子时的棋盘,第三种图标代表皇后棋子。
本代码在求解过程中每求解出一个解便输出此时的棋盘信息,最终输出解的数字。
2、多皇后问题
本代码参数n代表皇后数量,过输入n值改变即为求解多皇后问题:

在这里插入图片描述

六.结果分析
本次作业通过查询资料了解了八皇后问题的由来和含义,然后采用回溯算法来完成了这个项目的主体部分,简要输出棋盘信息的同时,拓展了多皇后问题。
七.作业体会
纸上得来终觉浅,亲手实践方能将知识真正理解。透彻八皇后算法虽然不算是难度偏高的例子,但是对于我这样刚刚了解人工智能的大学生而言,拥有恰到好处的挑战性,通过努力还是可以完成算法并实现它的展示。这个过程让我复习了回溯思想并加深了我对人工智能的理解。
八.参考资料
《人工智能(21世纪高等学校计算机专业实用规划教材)》清华大学出版社
《八皇后问题》百度百科
九.附件(源代码)

#include <iostream>
using namespace std;
int c[20], n, num=0;//c[20]保存每一行棋子的位置,n为皇后数目,num为解数
void print(){

    for(int i=0; i<n; i++){
        for(int j=0; j<n; j++){
            if(j == c[i]) cout<<"※ ";//如果该位置为记录好的解中棋子位置,则输出棋子
            else if((i+j)%2==0) cout<<"□ ";//无棋子处按棋盘样式输出棋盘
            else if((i+j)%2==1) cout<<"■ ";
        }
        cout<<endl;
    }
    cout<<endl;//每次输出完一个解法则输出一个空行隔开每个解法
}
void search(int r){
    if(r == n){//求得一解立即打印
        print();
        num++;
        return;
    }
    for(int i=0; i<n; i++)
        {
        c[r] = i;//第r行设第i列为皇后
        int ok = 1;
        for(int j=0; j<r; j++)
            if(c[r]==c[j] || r-j==c[r]-c[j] || r-j==c[j]-c[r])//检查此时皇后是否符合规则
            {
                ok = 0;//如果不符合规则返回上一次选择,更换皇后位置继续寻找
                break;
            }
        if(ok) search(r+1);//此时已有皇后符合规则,继续寻找下一个皇后
         }
}
int main(){
    cout<<"请输入皇后数量:"<<endl;
    cin>>n;
    search(0);
    cout<<num<<endl;
    return 0;
}

  • 8
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值