八皇后启发式搜索

待解决问题的解释

八皇后问题是一个以国际象棋为背景的问题:如何能够在 8×8 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。

问题的搜索形式描述

状态空间:用N维向量Qcol表示N*N的棋盘中N皇后的摆法,其中Qcol的第i个分量的值为棋盘第i行中皇后Q所在的列数。

操作规则:第一个皇后Q放在第1行,第k个皇后Q放在第k行且不能与之前所有的皇后互相攻击。

初始状态:Qcol向量的所有分量都为-1

后继函数:从第1行开始摆皇后,每摆完一行再摆下一行

目标测试:如果摆完N行皇后就算完成目标

路径耗散函数:认为第i+1行可供皇后备选的格子数量越多则耗散越低    

解决方案介绍

满足约束条件下,逐行放置皇后,使用启发式算法结合回溯法解决局面。

算法介绍

启发式算法的启发式函数返回值代表着下一行可供放置皇后的备选格子数,认为下一行的备选格数越多则更容易找到全局解法,这是一种贪心策略。当某一行皇后放置完后,计算出启发函数返回为0,且皇后未放置完,则回溯到上一状态,采用启发式函数返回值次大的放置方案。重复这一过程,直至解决问题,或认为问题无解。

算法伪代码

初始化描绘状态空间的向量Qcol

初始化存储启发式函数返回值的候选局面数组num_nextLineQ

从第一行开始摆放皇后

计算这一行皇后的候选位置是否存在(满足约束条件的位置),如果不存在,回溯到上一状态(上一行当前放置皇后的位置启发值置为-1,取次高启发值的位置放置皇后)

计算这一行皇后候选位置对应的启发函数返回值

在最高启发返回值(最小路径耗散)的位置放下皇后

开始摆放下一行的皇后,回到步骤4,直至摆完所有皇后或者尝试完所有的可能性发现问题无解,不输出结果。

算法实现

实验环境与问题规模

实验环境采用VS2010下的C++语言

时间复杂度为O(n2)

空间复杂度为O(n2)

数据结构

int Qcol[N];      //状态空间,N维向量代表着每一行中皇后Q所在的列数

int num_nextLineQ[N][N];      //num_nextLineQ[i][j]表示第i行j列放下一个Q后,第i+1行可以放下多少Q

int isUnavailable[3][2*N-1];    //iU[0][j]表示第j列有无皇后,iU[1][i+j]表示(i,j)正对角线有无皇后,iU[2][i+j]表示(i,j)反对角线有无皇后

实验结果

顺利找到8皇后的一种解法,当修改棋盘的尺寸进行N皇后问题的求解时,代码依然适用,但是碍于时间复杂度,当N过大时程序执行愈加缓慢,产生指数爆炸问题。

系统中间及最终输出结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lightypants

我需要你的帮助..

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值