python八皇后问题递归算法_算法回顾之:递归经典算法-八皇后问题

这篇博客回顾了经典的八皇后问题,介绍了如何使用递归算法在8×8棋盘上放置八个皇后,确保它们不会互相攻击。文章详细解释了解决方案的关键点,包括冲突判断和递归调用,并提供了Python代码实现。最后,展示了如何输出解决方案并指出总共有92种解。
摘要由CSDN通过智能技术生成

说起八皇后问题,它是一个古老而著名的问题,是回溯算法的典型案例。

该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,

高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。

二、关键点

从上面的描述我们可以得出,符合八皇后的解须符合下列三个条件:(行为y,列为x表示,也就是一个二维表)

1、所有皇后的x不相同

2、所有皇后的y不相同

3、不在同一对角线上

三、解体思维整理

1、所有皇后的x不相同解决方法:

很简单:直接用将要摆放的皇后的x与已摆放好的皇后的x对比,相等则冲突

2、所有皇后的y不相同解决方法:

这个其实可以不用处理,因为解决这个问题的根本就是一行只放一个皇后,当然,如果你转换一下,从列开始,一列一列来访,原理也是一样的,所以我们x和y,只需要处理一个就可以了

3、不能处于同一对角线上

这个需要点技巧,其实可以这样子,从下面可以分析出,只要Nx-Tx!=Ny-Ty,可以理解为两个方向的距离不能相等,(目前我是这样子理解的,有更好的方法可以留言一起学习哦)

0

1

2

3

4

5

6

7

1

T

2

N

3

4

5

6

7

四、编码实现

(突然想用python来编码,我们的python可是非常适合用来处理该类问题的哦,当然你用其他编程语言也是可以的,重要的是理解了解题思路即可)

1、我们先编写一个判断新摆放的皇后与已摆放的皇后是否冲突的判断方法:

#判断是否冲突

#state这里是用元组来实现,已摆放的皇后的X轴的值会通过state传递进来

#nextX 表示即将要摆放的皇后的X轴的值

def conflict(state,nextX):

#1)、获取已摆放的皇后的数量

nextY = len(state);

for i in range(nextY):

#2)、

tempX = abs(state[i] - nextX);

tempY = nextY - i;

if tempX in (0,tempY):

return True;

return False;

2)处的代码可以这样理解:tempX代表新增皇后老皇后(已摆放的皇后称为老皇后,方便表述,后面的我也会这样称呼哦)在X轴上的距离,tempY为新皇后与老皇后在Y轴上的距离

if tempX in (0,tempY):就很好理解了,判断tempX是元组(0,tempY)中的两个元素中的一个。为什么是0和tempY呢?

0:即X轴的值不能相等,相等不久处于同一列了么?这就冲突了哦

tmepY:前面解题思维整理有说,其就是保证x轴和Y轴方向上新皇后和老皇后的距离不能相等,相等就处于对角线上了哦

2、利用递归调用处理8皇后问题

#为了调用方便,我们提供了默认值

def queens(num=8,state=()):

for pos in range(num):

#1)判断pos是否冲突,pos代表X值

if not conflict(state,pos):

#2)重点,这里是递归的出口,当我们能够摆放下第8个皇后,也就代表我们之前的摆放策略是可行的

if len(state) == num-1:

yield (pos,);

else:

# 如果不是最后一个皇后,就递归调用queens方法

for result in queens(num,state+(pos,)):

yield (pos,)+result;

3、为了输出好看,我们增加一个打印方法

def prettyPrint(solution):

def prettyLine(pos,lenght = len(solution)):

return 'X'*(pos)+'0'+'X'*(lenght-pos-1);

for pos in solution:

print(prettyLine(pos));

4、一切准备就绪,我们来调用一下吧

for solution in queens():

print(solution)

prettyPrint(solution)

print("----------")

运行结构,一共有92个,我这里就只截取一个

(0, 4, 7, 5, 2, 6, 1, 3)

0XXXXXXX

XXXX0XXX

XXXXXXX0

XXXXX0XX

XX0XXXXX

XXXXXX0X

X0XXXXXX

XXX0XXXX

----------

总结:算法是程序的灵魂,每天进步一点,温故而知新;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值