N皇后问题(分支限界法)

news2024/11/19 7:44:17

问题描述:

在 n * n 格的棋盘上放置彼此不受攻击的 n 个皇后。按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题等价于在 n * n 的棋盘上放置 n 个皇后,任何 2个皇后不放在同一行或同一列或同一斜线上。

设计一个解 n 皇后问题的队列式分支限界法,计算在 n * n 个方格上放置彼此不受攻击的 n 个皇后的一个放置方案。

数据输入:

第一行有1个正整数 n 。

结果输出:

第一行是n个皇后的放置方案。

思路:

1.题目分析:

对于每一个放置点而言,它需要考虑四个方向上是否已经存在皇后。分别是行、列,45度斜线和135度斜线。

行:每一行只放一个皇后,直到我们把最后一个皇后放到最后一行的合适位置,则算法结束。

列:列相同的约束条件,只需判断 j 是否相等即可。

45度斜线和135度斜线:约束条件——当前棋子和已放置好的棋子不能存在行数差的绝对值等于列数差的绝对值的情况,若存在则说明两个棋子在同一条斜线上

2.算法选择:

用分支限界法来解决 n 皇后问题。对于该问题它满足两种树(子集树、排列树)结构。这里由于每一个合适的放置点出现最优解的概率是相等的,因此不需要使用优先队列。stl 提供了一个已经封装好的队列queue。

A.子集树。我们把行约束条件和其它约束条件放在一起,即认为每一行,棋子都有n个位置可以放置。于是它的空间结构如下:

 

(假设n = 3,这个图只画出了两层)

B.排列树。我们把行约束条件单独拿出来,也就是我们认为总共有八个皇后,这八个皇后必须都要放上去,但是放的位置不同,显然这是一个排列树。于是它的空间结构如下:

 

3.算法设计

1).数据存储

对于每一个棋子节点,它需要储存两个信息,一个是该棋子所处的层数,另一个就是这个棋子它是由哪些棋子扩展而来的,也就是它的路径。

//定义一个节点类
struct Node{
	int number;//棋子所处的层数,也就是棋盘上的i
	vector<int>x;//保存该棋子以及在它之前的棋子所在的列数j。也就是它的所有父辈节点的信息 
}; 

 比如图中的节点 m ,它储存的信息就是number = 3,x[1]=  1;x[2] = 2;x[3] = 3。指明了前面棋子的列信息。

2).定义一个Queen的类,封装一些相关的信息,比如皇后个数和最优解的数组

class Queen{
	friend int nQueen(int);
	public:
		bool Place(Node q,int n);
		void Research();
		int n;//皇后个数
		int *bestx;//最优解
};

4.细节处理

1).当前所处层数的判断:每一层的结尾都压入一个 number =  -1 的节点,每一次在取出队列中的节点时进行判断如果该节点的 number = -1,那么当前层数 t 加 1,并且再压入一个 number = -1的节点。然后重新往队列取出下一个节点。

2).算法终止条件:如果当前取出的节点 number == n,表明已经处理到最后一层了,并且最后一层满足约束条件的棋子位置已经都存在队列中了。这时我们把当前节点的数组 x 赋值给 bestx ,然后结束算法。

Code:

#include<bits/stdc++.h>
using namespace std;

//定义一个节点类
struct Node{
	int number;
	vector<int>x;//保存当前解 
}; 
 
//定义一个Queen的类 
class Queen{
	friend int nQueen(int);
	public:
		bool Place(Node q,int n);
		void Research();
		int n;//皇后个数
		int *bestx;//最优解
}; 
 
//判断是否能够放置的函数 
bool Queen::Place(Node q,int n){
	for(int j = 1;j < n;j ++ )
	  if((abs(n-j) == abs(q.x[j] - q.x[n])) || (q.x[j] == q.x[n])) 
	    return false;
	return true;
}
 
void Queen::Research(){
	queue<Node>Q;//活节点队列
	Node sign;
	sign.number = -1;
	Q.push(sign);//同层节点尾部标志
	int t = 1;//当前节点所处的层
	Node Ew;//当前扩展节点 
	Ew.number = 0; 
	//搜索子集空间树
	while(1){	
	   //检查所有的孩子节点 
	   for(int k = 1;k <= n;k ++ ){
		//把当前扩展节点的值赋给下一个节点 
		Node q;
	        q.number = t; 
	        q.x.push_back(0);//第一个位置为0 
    	        for(int i = 1;i < t;i ++ ) q.x.push_back(Ew.x[i]);
    	        q.x.push_back(k);
		if(Place(q,t))
    	    	Q.push(q);
    	    }	 
		//取下一扩展节点,取出,赋值给Ew 
		Ew = Q.front();
		Q.pop();
		if(Ew.number == -1){
		    //同层节点尾部标记
		    t ++ ;//进入下一层 
		    Q.push(sign);//增加标记
		    //继续往下去下一个节点 
		    Ew = Q.front();
		    Q.pop();
		}		
		if(Ew.number == n){//找到最后一层的节点 
		   for(int i = 0;i <= n;i ++ ) bestx[i] = Ew.x[i];
		   break;
		} 
	}
}
 
int nQueen(int n){
	Queen X;
	X.n = n;	
	X.bestx = new int[n+1];
	for(int i = 0;i <= n;i ++ ) X.bestx[i] = 0;
	X.Research();
	for(int i = 1;i <= n;i ++ ) cout<<X.bestx[i]<<" ";
}
 
int main(){	
	int N;
	cin>>N;
	nQueen(N);
	return 0;
}

代码运行截图:

 

 


 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/62880.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Ansys Speos | 新型计算方法:使用 GPU 提升计算速率

前言 Speos 在2022R2版本中正式推出 GPU 计算功能&#xff0c;相比于 CPU 计算&#xff0c;相同HPC32配置&#xff0c;高性能显卡在仿真计算中将会更显计算优势&#xff0c;在仿真数据量大、材料属性复杂、光源种类多的条件下&#xff0c;Speos 视觉模拟会消耗更多仿真计算时间…

ARM异常处理(1):异常类型、优先级分组和异常向量表

本系列文章将以Cortex-M3内核为例&#xff0c;对ARM的异常(exception)进行分析。 文章目录1 异常类型2 优先级3 向量表1 异常类型 Cortex-M3提供了一个功能丰富的异常体系结构&#xff0c;它支持很多系统异常和外部中断。异常编号1-15表示系统异常&#xff0c;16及以上表示外部…

0116 查找算法 Day5

剑指 Offer 04. 二维数组中的查找 在一个 n * m 的二维数组中&#xff0c;每一行都按照从左到右 非递减 的顺序排序&#xff0c;每一列都按照从上到下 非递减 的顺序排序。请完成一个高效的函数&#xff0c;输入这样的一个二维数组和一个整数&#xff0c;判断数组中是否含有该…

2022快手电商短视频运营白皮书:Q2对比Q1GMV总值增长率达12%

1、2022快手电商短视频运营白皮书&#xff1a;Q2对比Q1GMV总值增长率达12%新榜讯 12月2日&#xff0c;快手电商发布《2022快手电商短视频运营白皮书》。白皮书数据显示&#xff0c;2022年4-6月&#xff0c;随着平台商家对短视频渠道的认知提升&#xff0c;挂车短视频生产量不断…

【人脸识别】MVFace:一个优于CosFace和ArcFace的人脸识别损失

论文题目&#xff1a;《Mis-classifified Vector Guided Softmax Loss for Face Recognition》 论文地址&#xff1a;https://arxiv.org/pdf/1912.00833v1.pdf 代码地址&#xff1a;http://www.cbsr.ia.ac.cn/users/xiaobowang/ 1.背景 迄今为止&#xff0c;提出了几种基于mar…

Hashing to elliptic curve算法改进

1. 引言 前序博客有&#xff1a; ECDSA VS Schnorr signature VS BLS signature 第3节“BLS签名” 私钥pkpkpk&#xff0c;对应的公钥为PpkGPpk\times GPpkG。待签名消息mmm。 BLS signature的签名流程为&#xff1a; 1&#xff09;通过H(m)H(m)H(m)将消息mmm映射为point o…

计算机毕业论文java毕业设计选题源代码javaweb企业门户网站官网

&#x1f496;&#x1f496;更多项目资源&#xff0c;最下方联系我们✨✨✨✨✨✨ 目录 Java项目介绍 资料获取 Java项目介绍 《javaweb企业门户网站》该项目采用技术&#xff1a;jsp servlet mysqljdbccssjsjQuery等相关技术&#xff0c;项目含有源码、文档、配套开发软件…

[hadoop全分布部署]安装Hadoop、配置Hadoop 配置文件②

&#x1f468;‍&#x1f393;&#x1f468;‍&#x1f393;博主&#xff1a;发量不足 个人简介&#xff1a;耐心&#xff0c;自信来源于你强大的思想和知识基础&#xff01;&#xff01; &#x1f4d1;&#x1f4d1;本期更新内容&#xff1a;安装Hadoop、配置Hadoop 配置文件…

手把手教你SSM整合(包教包会)

SSM整合 步骤&#xff08;七步&#xff09; 新建maven项目&#xff0c;添加依赖 可以选择根据模版创建maven项目 <dependencies><!--spring-webmvc--><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc&…

OpenCV入门(C++/Python)- 使用OpenCV调整尺寸大小(三)

使用OpenCV调整图像大小。要调整图像的大小&#xff0c;可以根据每个轴&#xff08;高度和宽度&#xff09;进行缩放&#xff0c;考虑指定的缩放因素&#xff0c;或者只需设置所需的高度和宽度。 调整图像大小时&#xff1a; 如果想在调整后的图像中保持相同的宽高比&#xf…

Redis 7.0 源码调试环境搭建与源码导读技巧

天下武功&#xff0c;无坚不摧&#xff0c;唯快不破&#xff01;我的名字叫 Redis&#xff0c;全称是 Remote Dictionary Server。 有人说&#xff0c;组 CP&#xff0c;除了要了解她外&#xff0c;还要给机会让她了解你。 那么&#xff0c;作为开发工程师的你&#xff0c;是否…

物联网设备带你进入物联网时代,轻松实现数据互联互通

物联网这一词&#xff0c;我们在生活和工作中时常会接触到&#xff0c;但如果要问大家什么是物联网设备&#xff1f;物联网设备有哪些&#xff1f;很多人应该没有一个详细的概念。那么什么是物联网设备呢&#xff1f;物联网设备是指能够连接无线网络&#xff0c;并具有数据传输…

【电力系统经济调度】多元宇宙算法求解电力系统多目标优化问题(Matlab实现)【电气期刊论文复现与算例创新】

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️❤️&#x1f4a5;&#x1f4a5;&#x1f4a5; &#x1f4dd;目前更新&#xff1a;&#x1f31f;&#x1f31f;&#x1f31f;电力系统相关知识&#xff0c;期刊论文&…

计算机网络复习笔记——运输层

计算机网络复习笔记——运输层 概述 在计算机网络中进行通信的真正实体是位于通信两端主机中的进程 运输层的不同端口对应不同的进程 根据应用需求不同&#xff0c;运输层为应用层提供两种不同的运输协议&#xff0c;面向连接的TCP和无连接的UDP协议 运输层端口号、复用与…

CSS-盒子模型-内容,边框,内边距,外边距,(合并,塌陷情况)

CSS-盒子模型-内容&#xff0c;边框&#xff0c;内边距&#xff0c;外边距&#xff0c;(合并&#xff0c;塌陷情况) 目标&#xff1a;能够认识 盒子模型的组成 &#xff0c;****能够掌握盒子模型 边框、内边距、外边距 的****设置方法 学习路径&#xff1a; 1. 盒子模型的介绍 …

RK3588开发板的性能参数、功耗及功能特点|飞凌动态讲解

内容来源&#xff1a;飞凌嵌入式官网-www.forlinx.com2021年12月16日第六届瑞芯微开发者大会上&#xff0c;瑞芯微发布了全新一代旗舰处理器——RK3588。 相较前一代产品&#xff0c;RK3588的性能提高20%~30%&#xff01;同时采用新一代8nm制程工艺&#xff0c;也将大幅度降低功…

超级菜鸟怎么学习数据分析?

超级菜鸟如何学习数据分析&#xff0c;如何有效的成长为专业高手。 这个问题跟把大象放进冰箱是一个道理。 菜鸟成为超级高手是只需要四个步骤&#xff0c;直接上干货。 快速上手&#xff1a;可以简单、低门槛的上手学习与使用&#xff0c;快速入门 快速上手数据分析无非就是选…

Logstash:运用 Elasticsearch filter 来丰富地理数据

我们知道丰富数据对于很多的应用来说非常重要。这涉及到访问不同的表格&#xff0c;并进行搜索匹配。找到最为相近的结果并进行丰富数据。针对 Elasticsearh 来说&#xff0c;我们可以通过 enrich processor来进行丰富。你可以阅读我之前的文章来了解更多&#xff1a; Elastics…

git commit -m 撤销操作

1. 撤销本次commit-m操作 返回到add成功状态 git reset --soft HEAD^ 2.撤销本次commitadd 返回本地未提交状态 git reset --hard HEAD^ HEAD^ 表示上一个版本&#xff0c;即上一次的commit&#xff0c;几个^代表几次提交&#xff0c;如果回滚两次就是HEAD^^。 也可以写成HEAD…

代码随想录算法训练营第五十五天| LeetCode392. 判断子序列、LeetCode115. 不同的子序列

一、LeetCode392. 判断子序列 1&#xff1a;题目描述&#xff08;392. 判断子序列&#xff09; 给定字符串 s 和 t &#xff0c;判断 s 是否为 t 的子序列。 字符串的一个子序列是原始字符串删除一些&#xff08;也可以不删除&#xff09;字符而不改变剩余字符相对位置形成的新…