八皇后问题

先抄了一篇代码。

原理:任意两个皇后不在同一行同一列,且不在对角线上。这里是简单的N*N矩阵棋盘(即在N*N棋盘上讨论N皇后的问题)


脚本如下:

def conflict(state, nextX):
    nextY = len(state)  
    for i in range(nextY):
        if abs(state[i] - nextX) in (0, nextY - i): # 0:在同一列上;后者代表在对角线上
            return True
    return False

def queens(num, 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,)):
                    print result, pos
                    yield (pos,) + result

print len(list(queens(8)))

结果为92,说明8*8的棋盘上8皇后的解有92个。

此脚本并未关注问题本身存在的对称性等特点,仅仅根据题目要求使用递归方法解出所有解。

下面分析一下源码:

1. queens(8)提供了一个8*8的棋盘上8皇后的问题。

2. conflict函数用来判断递归的数是否满足要求,state为一个元组代表已知皇后的位置,nextX为下一个皇后所在行,Y为所在列。满足(皇后可共存)返回False。

    abs(state[i] - nextX) in (0, nextY - i):检查两个皇后是否同列(同行并未判断,因为默认下一个皇后在下一列),或者两个皇后是否在同一对角线(到行的距离等于到列的距离)

3. queens()为一个递归循环,利用yield产生最后的结果


以4*4为例进行单步运行:


序号statepos序号statepos序号statepos
1()010(0, 3)019(1,)0
2(0,)011(0, 3)120(1,)1
3(0,)112(0, 3, 1)021(1,)2
4(0,)213(0, 3, 1)122(1,)3
5(0, 2)014(0, 3, 1)223(1, 3)0
6(0, 2)115(0, 3, 1)324(1, 3, 0)0
7(0, 2)216(0,3 )225(1, 3, 0)1
8(0, 2)317(0, 3)326(1, 3, 0)2
9(0,)318()127()1

可以看到,在运行到26步时找到了第一组解(1,3,0,2)。同理找到另一组解,另一组解为(2,0,3,1)。可以看出两组解是对称的(该问题的简化解法,利用棋盘的对称性)。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值