python解八皇后问题(一)

八皇后问题描述

国际象棋8*8棋盘,64个位置,放8个皇后,皇后可以横竖斜线吃子,因此每个皇后所在的行、列和斜线都不能放皇后。

小于5*5的棋盘无法每行放一个皇后,因此从五皇后以上可解N皇后问题。

程序函数功能描述

  • 8*8棋盘用二位数据表示,初始全部为0,落子的位置改为1.
  • allow_luozi函数判断某个位置是否可以落子,对于一个待判断的位置(x, y),如果以下位置都没有皇后,则可以落子:
    1. 它上面每一行的y列位置
    2. 它的左上斜线的每个位置
    3. 它的右上斜线的每个位置
  • eight_quene函数递归从左上角开始逐行尝试落子,每一行从左到右尝试,因此allow_luozi函数只需要判断当前位置的上、左上和右上三条线。如果一个位置可以落子,就落子然后在下一行落子。
    如果一行没有位置可以落子,就向上回溯,把上一行的皇后从它的位置改到下一个可以落子的位置。当落子位置在最底下一行时,就找到了一个解,将它打印出来。然后把最底下一行的皇后拿走,向上回溯,将上一行的皇后改到下一个可以落子的位置。这样通过不断的递归和回溯找到全部解。

代码

n = 8
count = 0

board = [[0 for _ in range(n)] for _ in range(n)]


def allow_luozi(x, y):
    if any([board[i][y] for i in range(x)]) \
        or any([board[x-i][y-i] for i in range(1, n) if x - i >= 0 and y - i >= 0]) \
            or any([board[x - i][y + i] for i in range(1, n) if x - i >= 0 and y + i < n]):
        return False
    else:
        return True


def eight_quene(x=0, y=0):
    if y == n:
        if x == 0:
            print('finished')
            return
        else:
            x -= 1
            y = board[x].index(1)
            board[x][y] = 0
            eight_quene(x, y+1)
    else:
        if allow_luozi(x, y):
            board[x][y] = 1
            if x == n - 1:
                global count
                count += 1
                print(count)
                for line in board:
                    print(line)
                print()
                board[x][y] = 0
                x -= 1
                y = board[x].index(1)
                board[x][y] = 0
                eight_quene(x, y+1)
            else:
                eight_quene(x+1, 0)
        else:
            eight_quene(x, y+1)

程序执行遇到的问题

六皇后以上运行程序报错:

RecursionError: maximum recursion depth exceeded in comparison

递归深度超过限制了,这时候问谁最好使?——stackoverflow啊,弄不好网站就是因为这个问题得名的。python递归栈有限制,可以通过设置调大。

import sys
sys.setrecursionlimit(100000)

这样执行不报错了,但是仍然不能执行完,有个负值的退出码:

Process finished with exit code -1073741571 (0xC00000FD)

https://msdn.microsoft.com/en-us/library/cc704588.aspx查询错误代码,仍然是栈溢出,递归太多了。so有提到windows的问题,于是在linux上试了一下,可以执行完成:

91
[0, 0, 0, 0, 0, 0, 0, 1]
[0, 0, 1, 0, 0, 0, 0, 0]
[1, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 1, 0, 0]
[0, 1, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 1, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 1, 0]
[0, 0, 0, 1, 0, 0, 0, 0]
()
92
[0, 0, 0, 0, 0, 0, 0, 1]
[0, 0, 0, 1, 0, 0, 0, 0]
[1, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 1, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 1, 0, 0]
[0, 1, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 1, 0]
[0, 0, 0, 0, 1, 0, 0, 0]
()

我在windows的虚拟机和ubuntu子系统上执行都是只能输出前90种解法,可能跟操作系统还是有关系。

5-8皇后的摆法

  • 五皇后10种
  • 六皇后4种
  • 七皇后40种
  • 八皇后92种

猜你喜欢

转载自blog.csdn.net/qq_35753140/article/details/80011581
今日推荐