八皇后问题描述
国际象棋8*8棋盘,64个位置,放8个皇后,皇后可以横竖斜线吃子,因此每个皇后所在的行、列和斜线都不能放皇后。
小于5*5的棋盘无法每行放一个皇后,因此从五皇后以上可解N皇后问题。
程序函数功能描述
- 8*8棋盘用二位数据表示,初始全部为0,落子的位置改为1.
- allow_luozi函数判断某个位置是否可以落子,对于一个待判断的位置(x, y),如果以下位置都没有皇后,则可以落子:
- 它上面每一行的y列位置
- 它的左上斜线的每个位置
- 它的右上斜线的每个位置
- 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种