人工智能实验二:约束满足问题

news/2024/7/15 17:21:02 标签: 算法, 图论, c++

一、实验目的

  1. 求解约束满足问题;
  2. 使用回溯搜索算法求解八皇后问题。

二、实验平台

课程实训平台https://www.educoder.net/paths/369

三、实验内容及步骤

实训内容:2-4 第六章 约束满足问题

1.问题描述

八皇后问题是指在一个 8×8 的棋盘上摆放八个皇后,使得任意两个皇后都不能处于同一行、同一列或同一对角线上。因此,每行只能放一个皇后。

2.算法步骤

  1. 从第一行开始,枚举每个位置,判断该位置是否可以放置皇后,如果可以,则将皇后放置在该位置。
  2. 标记该列、主对角线和副对角线已被占用。
  3. 如果已经放置了8个皇后,增加计数器,回溯到上一行,将上一行皇后的位置改变,继续搜索下一列。
  4. 如果当前行没有找到合适的位置,回溯到上一行,将上一行皇后的位置改变,继续搜索下一列。
  5. 如果已经搜索完所有情况,结束搜索。

3.算法原理

回溯法是一种通过不断试错来解决问题的算法。在八皇后问题中,算法通过枚举每个位置,判断该位置是否可以放置皇后,如果可以则继续搜索下一行,否则回溯到上一行。在回溯的过程中,算法撤销之前放置的皇后和标记数组,继续搜索下一列。通过不断尝试,最终找到符合要求的解。回溯算法虽然简单,但是效率较低,因为需要穷举所有可能的情况

4.代码实现

该代码中的 searchh 函数用于在第 i 行搜索可以放置皇后的位置。在每一行中,每个皇后都有 8 个位置(列)可以试放。在尝试放置一个皇后时,需要检查该列、主对角线和副对角线是否已经被占用。

其中,b 数组记录了每一列是否已经有皇后占据,c 数组记录了主对角线是否已经有皇后占据,d 数组记录了副对角线是否已经有皇后占据。主对角线和副对角线的编号分别为 i+j 和 i-j+7。

如果已经放置了 8 个皇后,则增加计数器 sum 的值。如果没有放置完 8 个皇后,则继续在下一行搜索可行的位置。在回溯时,需要撤销之前放置的皇后和标记数组

核心代码如下:

void searchh(int i)
{
    for (int j = 1; j <= 8; j++)
    {
        if ((!b[j]) && (!c[i + j]) && (!d[i - j + 7]))//每个皇后都有八个位置(列)可以试放
        {
            /********** Begin **********/
            // 在(i,j)位置放置一个皇后
            a[i] = j;
            // 标记该列、主对角线、副对角线已被占用
            b[j] = c[i + j] = d[i - j + 7] = 1;
            // 如果已经放置了8个皇后
            if (i == 8)
            {
                // 增加计数器
                sum++;
            }
            else
            {
                // 在下一行搜索可行的位置
                searchh(i + 1);
            }
            // 回溯时撤销之前放置的皇后和标记数组
            b[j] = c[i + j] = d[i - j + 7] = 0;

            /********** End **********/
        }
    }
}

5.源程序

#include<iostream>
using namespace std;

int a[9];
int b[9] = { 0 };
int c[16] = { 0 };
int d[16] = { 0 };
int sum = 0;

void searchh(int i)
{
    for (int j = 1; j <= 8; j++)
    {
        if ((!b[j]) && (!c[i + j]) && (!d[i - j + 7]))//每个皇后都有八个位置(列)可以试放
        {
            /********** Begin **********/
            // 在(i,j)位置放置一个皇后
            a[i] = j;
            // 标记该列、主对角线、副对角线已被占用
            b[j] = c[i + j] = d[i - j + 7] = 1;
            // 如果已经放置了8个皇后
            if (i == 8)
            {
                // 增加计数器
                sum++;
            }
            else
            {
                // 在下一行搜索可行的位置
                searchh(i + 1);
            }
            // 回溯时撤销之前放置的皇后和标记数组
            b[j] = c[i + j] = d[i - j + 7] = 0;

            /********** End **********/
        }
    }
}

int main()
{
    searchh(1);
    cout << sum;
    return 0;
}

6.运行结果分析

在这里插入图片描述

运行结果92表示八皇后问题共有92种不同的解法。每个解法对应着八个皇后在棋盘上不同的摆放位置,满足每个皇后都不在同一行、同一列或同一对角线上的要求。由于八皇后问题的对称性,解法数量为92种。这个结果也可以通过计算八皇后问题的总解数来得到,其总解数为92。说明程序运行正确。

四、实验总结

本次实验中,我们使用回溯法解决了八皇后问题。通过枚举每个位置,判断该位置是否可以放置皇后,如果可以,则将皇后放置在该位置,并标记该列、主对角线和副对角线已被占用。如果已经放置了8个皇后,则增加计数器,回溯到上一行,将上一行皇后的位置改变,继续搜索下一列。如果当前行没有找到合适的位置,则回溯到上一行,将上一行皇后的位置改变,继续搜索下一列。最终,找到所有符合要求的解法。

在实验中,我们编写了八皇后问题的回溯法算法,并通过编写测试用例对算法进行了验证。测试结果表明,该算法能够正确地解决八皇后问题,并得到了92种不同的解法。算法的时间复杂度为 O(8^8),由于其需要枚举所有情况,所以效率相对较低,但对于八皇后问题这种规模较小的问题,仍然可以得到较好的解决。

在实验中,我们编写了八皇后问题的回溯法算法,并通过编写测试用例对算法进行了验证。测试结果表明,该算法能够正确地解决八皇后问题,并得到了92种不同的解法。算法的时间复杂度为 O(8^8),由于其需要枚举所有情况,所以效率相对较低,但对于八皇后问题这种规模较小的问题,仍然可以得到较好的解决。

在本次实验中,我深刻理解了回溯法算法的原理和实现过程,同时也了解到了八皇后问题这一经典问题。通过编写代码和测试用例,我掌握了如何使用回溯法算法解决问题,并在调试过程中积累了一定的编程经验。


http://www.niftyadmin.cn/n/232285.html

相关文章

MySQL数据库,数据的约束

目录 1.数据的约束 1.1约束的类型 1.2NULL约束 1.3UNIQUE约束 1.4DEFAULT约束 1.5PRIMARY KEY约束 1.6FOREIGN KEY约束 1.数据的约束 首先&#xff0c;创建一个名为test的数据库&#xff1a; mysql> create database test charset utf8; Query OK, 1 row affected …

[Java]Session机制

什么是Session Session是另一种记录客户状态的机制&#xff0c;不同的是Cookie保存在客户端浏览器中&#xff0c;而Session保存在服务器上。客户端浏览器访问服务器的时候&#xff0c;服务器把客户端信息以某种形式记录在服务器上。这就是Session。客户端浏览器再次访问时只需…

【Spring Security】 入门实战

文章目录一、基本概念二、Spring Security第一个程序三、Spring Security没有生效四、修改默认账号密码&#xff08;appliction.yml&#xff09;五、修改默认账号密码&#xff08;配置类&#xff09;六、Spring Security的三个configure方法七、Spring Security的三种身份的验证…

如何使用移位操作来实现乘法运算

把一个数向左移动n位相当于把该数乘以2的n次方&#xff0c;因此当乘法运算中的某个数字满足这个特点时&#xff0c;就可以用移位操作来代替乘法操作&#xff0c;从而提高效率。 演示代码如下&#xff1a; /*** author 阿水* create 2023-04-15 15:45* 把一个数向左移动n位相当…

Python里的元组、列表和字典区别

列表&#xff1a;可更改、有序、可重复、元素可以是任何对象 列表示例&#xff1a;[1,a,[2,3]] 元组&#xff1a;不可更改、有序、可重复、元素可以是任何对象 元组示例&#xff1a;(b,1,[2,3]) 字典&#xff1a;可更改、无序、键不可重复、键不可变、值可以是任何对象&…

【零基础学习】Javascript 快速入门(完整篇)简单、适合初学者

【零基础学习】Javascript 快速入门前言&#xff1a;如何解决错误提示&#xff08;Error&#xff09;Uncaught TypeError: Cannot set properties of null (setting innerHTML)Uncaught ReferenceError: displayDate is not defined at HTMLButtonElement.onclick安装Visual St…

java获取请求ip的方法

在上篇文章中我们介绍了 java获取请求 ip的方法&#xff0c;那么这篇文章我们就来详细讲解下获取请求 ip的方法。获取请求 ip的方法是基于 HTTP协议的&#xff0c;其原理如下&#xff1a; 1、用 web应用程序&#xff0c;将 web服务器端与客户端通过 HTTP协议通信。 2、客户端发…

免费的语音转文字软件有哪些?推荐一款好用的

随着人工智能技术的不断发展&#xff0c;语音识别技术已经得到了广泛的应用。语音转文字软件是其中的一种应用&#xff0c;它能够将人们说出的话语自动转化为文字&#xff0c;从而方便人们进行文本处理、记录、存档等操作。在现实生活中&#xff0c;有很多人需要使用语音转文字…