八皇后问题

来源:互联网 发布:lte无线网络优化 编辑:程序博客网 时间:2024/05/01 15:26

先抄了一篇代码。

原理:任意两个皇后不在同一行同一列,且不在对角线上。这里是简单的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 Falsedef 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,) + resultprint 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序号statepos1()010(0, 3)019(1,)02(0,)011(0, 3)120(1,)13(0,)112(0, 3, 1)021(1,)24(0,)213(0, 3, 1)122(1,)35(0, 2)014(0, 3, 1)223(1, 3)06(0, 2)115(0, 3, 1)324(1, 3, 0)07(0, 2)216(0,3 )225(1, 3, 0)18(0, 2)317(0, 3)326(1, 3, 0)29(0,)318()127()1

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





0 0