【算法导论】八皇后问题的算法实现(C、MATLAB、Python版)

简介:         八皇后问题是一道经典的回溯问题。问题描述如下:皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。如何将8个皇后放在棋盘上(有8*8个方格),使它们谁也不能被吃掉?         看到这个问题,最容易想到的就是遍历穷举法,不过仔细一想,思路虽然非常清晰,但是需要遍历次数太多,时间复杂度很高。
        八皇后问题是一道经典的回溯问题。问题描述如下:皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。如何将8个皇后放在棋盘上(有8*8个方格),使它们谁也不能被吃掉?
        看到这个问题,最容易想到的就是遍历穷举法,不过仔细一想,思路虽然非常清晰,但是需要遍历次数太多,时间复杂度很高。那么,我们应该怎么办呢?下面给出算法思路:
        算法思想:首先尝试在第一行放置第一个皇后,然后在第二行放置第二个使之与前面的皇后不构成威胁,依此类推。如果发现不能放置下一个皇后,就回溯到上一步,试着将皇后放在其他的位置。最后,或者尝试完所有的可能或者找到解决方案。
        这种算法思想与中国的一句古话“不撞南墙不回头”类似:一路向前走,直到走到死胡同,然后往回走,回到上一个岔路口,重新选择一个方向,继续向前走,直到到达目的地。
        下面给出了该算法的具体实现,用C、MATLAB、PYTHON分别进行了实现,由于程序给出了比较详细的注释,因此就不对具体程序解释说明了。

C语言实现:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define N 8//棋盘大小

int matrix[N][N];//存储皇后的位置,其实也可以用一维数组表示

void PrintQueen();//打印棋盘
void PlaceQueen(int row);//放置皇后
int Conflict(int row,int col);//检查当前皇后是否与之前的冲突

int main()
{
    PlaceQueen(0);
    return 0;
}

void PrintQueen()
{
    static int solutionNum=0;//看总共有多少种情况
    solutionNum+=1;
    int row,col;
    printf("第%d种方法:\n",solutionNum);
    for(row=0;row<N;row+=1)
    {
        for(col=0;col<N;col+=1)
        {
            if(matrix[row][col])
            {
                printf("* ");
            }
            else
            {
                printf("- ");
            }
        }
        printf("\n");
    }
    printf("\n");
}

int Conflict(int row,int col)
{
	for (int m = 0; m <row ; m++) 
	{  
        for (int n = 0; n <N; n++)
		{   
            if (matrix[m][n] == 1) //  每一行只有一个皇后  
			{  
                if ( n == col || abs(row - m) == abs(col - n) )   // 检查是否与之前的皇后冲突
                    return false;  
            }  
        }  
    }  
    return true;
}

void PlaceQueen(int row)
{
	if(row>=N)//已经放置了N个皇后
	{
		PrintQueen();
	}
	else
	{
		for(int col=0;col<N;col++)
		{
			matrix[row][col]=1;
			if(row==0||Conflict(row,col))
					PlaceQueen(row+1);//递归调用		
			matrix[row][col]=0;		
		}
		
	}
	
}

MATLAB实现

脚本文件Queen.m

 clear all
clc
 
global solutionNum;
solutionNum=0;%全局变量记录方法数
N=8;%皇后个数
matrix=zeros(N);%存储皇后位置信息
 
PlaceQueen(1,matrix,N)%调用放置方法


函数文件PlaceQueen.m

function PlaceQueen(row,matrix,N)%回溯法放置皇后
 
    if row>N
        PrintQueen(N,matrix);%打印棋盘
    else
        for col=1:N
            matrix(row,col)=1;
            if row==1||Conflict(row,col,N,matrix)%检测是否冲突
                PlaceQueen(row+1,matrix,N);
            end
            matrix(row,col)=0;
        end
    end
    
    %子函数:检测冲突
    function result=Conflict(row,col,N,matrix)%检测是否冲突
 
    result=1;
    for i=1:row-1
        for j=1:N
            if matrix(i,j)==1
                if ((j==col)||(abs(row-i)==abs(col-j)))%是否产生冲突:在同一直线,斜线上
                    result=0;
                    break;
                end
            end
        end
        if result==0
            break;
        end
    end
     
    %子函数:打印棋盘信息
function PrintQueen(N,matrix)
 
    global solutionNum; %定义全局变量,来累积方法数
    solutionNum=solutionNum+1;
    
    disp(['第',num2str(solutionNum),'种方法:'])
 
disp(matrix)

PYTHON实现:

def conflict(state,nextX):#冲突检测函数
    nextY=len(state)
    for i in range(nextY):
        if abs(state[i]-nextX) in (0,nextY-i):#检测是否在同一直线、斜线
            return True
    return False

def queens(num=8,state=()): #放置皇后,采用元组state来存储皇后的位置
    for pos in range(num):
        if not conflict(state,pos):
            if len(state)==num-1:
                yield (pos)
            else:
                for result in queens(num,state+(pos,)):
                    yield (pos,)+result



for solution in queens(8):
    print (solution)
    
print('总共的方法数为:',len(list(queens(8))))

运行结果分别如下:

1、C语言的运行结果:


2、MATLAB语言的运行结果:


3、PYTHON语言的运行结果:
 

扩展:

上面的程序中,改变N的值就可以解决N皇后的问题了, 但还可以 用分治法来解决N皇后的问题,具体参见文献 《N皇后问题解的构造和等价性分析》。下面的Matlab程序给出了一个简单的算法过程:
4皇后的一种放置方式:
     0     0     1     0
     1     0     0     0
     0     0     0     1
     0     1     0     0
根据4皇后的放置方式可以推导出16皇后的一种放置方式:
     0     0     0     0     0     0     0     0     0     0     1     0     0     0     0     0
     0     0     0     0     0     0     0     0     1     0     0     0     0     0     0     0
     0     0     0     0     0     0     0     0     0     0     0     1     0     0     0     0
     0     0     0     0     0     0     0     0     0     1     0     0     0     0     0     0
     0     0     1     0     0     0     0     0     0     0     0     0     0     0     0     0
     1     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0
     0     0     0     1     0     0     0     0     0     0     0     0     0     0     0     0
     0     1     0     0     0     0     0     0     0     0     0     0     0     0     0     0
     0     0     0     0     0     0     0     0     0     0     0     0     0     0     1     0
     0     0     0     0     0     0     0     0     0     0     0     0     1     0     0     0
     0     0     0     0     0     0     0     0     0     0     0     0     0     0     0     1
     0     0     0     0     0     0     0     0     0     0     0     0     0     1     0     0
     0     0     0     0     0     0     1     0     0     0     0     0     0     0     0     0
     0     0     0     0     1     0     0     0     0     0     0     0     0     0     0     0
     0     0     0     0     0     0     0     1     0     0     0     0     0     0     0     0
     0     0     0     0     0     1     0     0     0     0     0     0     0     0     0     0
依次类推,可以得到4的幂次皇后的一种放置方式,不过 值得注意的是2、3、8、9、14、15、26、27、38、39这10个N值不能采用这种分治法。
由4皇后直接推出16皇后的Matlab实现如下:
clear all
clc
 
a4=[  0     0     1     0
     1     0     0     0
     0     0     0     1
     0     1     0     0]
 [asize bsize]=size(a4);
 
 a16=zeros(asize^2,bsize^2);
 [rowIndex,colIndex]=find(a4);
 
 for i=1:length(rowIndex)
     a16((1+asize*(rowIndex(i)-1)):asize*rowIndex(i),(1+asize*(colIndex(i)-1)):asize*colIndex(i))=a4;
 end
 a16


运行结果如下:



原文:http://blog.csdn.net/tengweitw/article/details/44648249
作者:nineheadedbird










目录
相关文章
|
8天前
|
算法 安全 数据安全/隐私保护
基于game-based算法的动态频谱访问matlab仿真
本算法展示了在认知无线电网络中,通过游戏理论优化动态频谱访问,提高频谱利用率和物理层安全性。程序运行效果包括负载因子、传输功率、信噪比对用户效用和保密率的影响分析。软件版本:Matlab 2022a。完整代码包含详细中文注释和操作视频。
|
20天前
|
存储 机器学习/深度学习 算法
蓝桥杯练习题(三):Python组之算法训练提高综合五十题
蓝桥杯Python编程练习题的集合,涵盖了从基础到提高的多个算法题目及其解答。
36 3
蓝桥杯练习题(三):Python组之算法训练提高综合五十题
|
5天前
|
人工智能 算法 数据安全/隐私保护
基于遗传优化的SVD水印嵌入提取算法matlab仿真
该算法基于遗传优化的SVD水印嵌入与提取技术,通过遗传算法优化水印嵌入参数,提高水印的鲁棒性和隐蔽性。在MATLAB2022a环境下测试,展示了优化前后的性能对比及不同干扰下的水印提取效果。核心程序实现了SVD分解、遗传算法流程及其参数优化,有效提升了水印技术的应用价值。
|
4天前
|
机器学习/深度学习 人工智能 算法
【车辆车型识别】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+算法模型
车辆车型识别,使用Python作为主要编程语言,通过收集多种车辆车型图像数据集,然后基于TensorFlow搭建卷积网络算法模型,并对数据集进行训练,最后得到一个识别精度较高的模型文件。再基于Django搭建web网页端操作界面,实现用户上传一张车辆图片识别其类型。
12 0
【车辆车型识别】Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+算法模型
|
6天前
|
机器学习/深度学习 算法 数据安全/隐私保护
基于贝叶斯优化CNN-LSTM网络的数据分类识别算法matlab仿真
本项目展示了基于贝叶斯优化(BO)的CNN-LSTM网络在数据分类中的应用。通过MATLAB 2022a实现,优化前后效果对比明显。核心代码附带中文注释和操作视频,涵盖BO、CNN、LSTM理论,特别是BO优化CNN-LSTM网络的batchsize和学习率,显著提升模型性能。
|
11天前
|
存储
基于遗传算法的智能天线最佳阵列因子计算matlab仿真
本课题探讨基于遗传算法优化智能天线阵列因子,以提升无线通信系统性能,包括信号质量、干扰抑制及定位精度。通过MATLAB2022a实现的核心程序,展示了遗传算法在寻找最优阵列因子上的应用,显著改善了天线接收功率。
|
9天前
|
机器学习/深度学习 算法 Java
机器学习、基础算法、python常见面试题必知必答系列大全:(面试问题持续更新)
机器学习、基础算法、python常见面试题必知必答系列大全:(面试问题持续更新)
|
13天前
|
监控 算法 数据安全/隐私保护
基于三帧差算法的运动目标检测系统FPGA实现,包含testbench和MATLAB辅助验证程序
本项目展示了基于FPGA与MATLAB实现的三帧差算法运动目标检测。使用Vivado 2019.2和MATLAB 2022a开发环境,通过对比连续三帧图像的像素值变化,有效识别运动区域。项目包括完整无水印的运行效果预览、详细中文注释的代码及操作步骤视频,适合学习和研究。
|
21天前
|
算法
基于粒子群算法的分布式电源配电网重构优化matlab仿真
本研究利用粒子群算法(PSO)优化分布式电源配电网重构,通过Matlab仿真验证优化效果,对比重构前后的节点电压、网损、负荷均衡度、电压偏离及线路传输功率,并记录开关状态变化。PSO算法通过迭代更新粒子位置寻找最优解,旨在最小化网络损耗并提升供电可靠性。仿真结果显示优化后各项指标均有显著改善。
|
16天前
|
机器学习/深度学习 算法 数据挖掘
基于GWO灰狼优化的GroupCNN分组卷积网络时间序列预测算法matlab仿真
本项目展示了基于分组卷积神经网络(GroupCNN)和灰狼优化(GWO)的时间序列回归预测算法。算法运行效果良好,无水印展示。使用Matlab2022a开发,提供完整代码及详细中文注释。GroupCNN通过分组卷积减少计算成本,GWO则优化超参数,提高预测性能。项目包含操作步骤视频,方便用户快速上手。