要求:在 8 * 8 的棋盘上,8 个皇后不在同行、同列、同对角线。
(1)定义冲突
>>> def conflict(state, nextX):
nextY = len(state)
for i in range(nextY):
if abs(state[i] - nextX) in (0, nextY - i):
return True
return False
其中,nextX 指下一个皇后将要放置的横坐标,也就是列。nextY 指下一个皇后将要放置的纵坐标,即行。state是一个列表,列表内存放着已经放置好的皇后的位置,即存放着元组 (x , y) ,state[ i ] = j 指第(i + 1)行的皇后在第(j + 1)列。
注: if abs(state[i] - nextX) in (0, nextY - i): 中的 (0, nextY - i): 指前面的数是否为 0 或者 nextY - i 两者中的一个,并不是指处在某个范围里面。
(2)放置皇后
>>> def queens(num = 8, 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,)):
yield (pos,) + result
注:程序分为 if len(state) == num - 1: 和 else: 两部分,是因为,递归都需要有一个递归结束的点,否则,递归就会无止境的不断进行下去。
其中, for pos in range(num): 这一行,指的是给将要放置的新皇后,她的纵坐标已固定(由定义冲突里的 nextY = len(state) 来固定的),所以,需要在8个列位置上,给她进行选择放置的位置。
如果放置 4 个皇后,则有 2 种放置方法:
>>> list(queens(4))
[(1, 3, 0, 2), (2, 0, 3, 1)]
应用 print 可以把不同的放置方法,一行一行打印出来。
(3)打包输出
输出简易的放置了皇后的棋盘。
>>> def prettyprint(solution):
def line(pos, length = len(solution)):
return '. ' * (pos) + 'X ' + '. ' * (length - pos - 1)
for pos in solution: #依次取出随机挑选的方案里的每个数,即每位皇后在自己的行中坐所在的列。
print (line(pos))
>>> import random
>>> prettyprint(random.choice(list(queens(8)))) #在queens(8) 的方案里随机挑选一个
. . X . . . . .
. . . . . X . .
. . . . . . . X
. X . . . . . .
. . . X . . . .
X . . . . . . .
. . . . . . X .
(1)定义冲突
>>> def conflict(state, nextX):
nextY = len(state)
for i in range(nextY):
if abs(state[i] - nextX) in (0, nextY - i):
return True
return False
其中,nextX 指下一个皇后将要放置的横坐标,也就是列。nextY 指下一个皇后将要放置的纵坐标,即行。state是一个列表,列表内存放着已经放置好的皇后的位置,即存放着元组 (x , y) ,state[ i ] = j 指第(i + 1)行的皇后在第(j + 1)列。
注: if abs(state[i] - nextX) in (0, nextY - i): 中的 (0, nextY - i): 指前面的数是否为 0 或者 nextY - i 两者中的一个,并不是指处在某个范围里面。
(2)放置皇后
>>> def queens(num = 8, 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,)):
yield (pos,) + result
注:程序分为 if len(state) == num - 1: 和 else: 两部分,是因为,递归都需要有一个递归结束的点,否则,递归就会无止境的不断进行下去。
其中, for pos in range(num): 这一行,指的是给将要放置的新皇后,她的纵坐标已固定(由定义冲突里的 nextY = len(state) 来固定的),所以,需要在8个列位置上,给她进行选择放置的位置。
如果放置 4 个皇后,则有 2 种放置方法:
>>> list(queens(4))
[(1, 3, 0, 2), (2, 0, 3, 1)]
应用 print 可以把不同的放置方法,一行一行打印出来。
(3)打包输出
输出简易的放置了皇后的棋盘。
>>> def prettyprint(solution):
def line(pos, length = len(solution)):
return '. ' * (pos) + 'X ' + '. ' * (length - pos - 1)
for pos in solution: #依次取出随机挑选的方案里的每个数,即每位皇后在自己的行中坐所在的列。
print (line(pos))
>>> import random
>>> prettyprint(random.choice(list(queens(8)))) #在queens(8) 的方案里随机挑选一个
. . X . . . . .
. . . . . X . .
. . . . . . . X
. X . . . . . .
. . . X . . . .
X . . . . . . .
. . . . . . X .
. . . . X . . .
#!bin/usr/python
def conflict(state,nextX):
nextY=len(state)
for i in range(nextY):
if abs(nextX-state[i]) in (0,nextY-i):
return True
return False
def queen(side_length,state=()):
for pos in range(side_length):
if not conflict(state,pos):
if len(state)==side_length-1:
yield (pos,)
else:
for result in queen(side_length,state+(pos,)):
yield (pos,)+result
def prettyprint(solution):
def line(pos, length = len(solution)):
return '.'*(pos) + 'X' + '.'*(length-pos-1)
for pos in solution:
print line(pos)
for solution in list(queen(4)):
prettyprint(solution)