Python中的8个皇后问题。
嗨!我只是开始教Python,所以有人可以解释下面写的代码(在Internet上找到)吗?有些代码对我来说很复杂。请解释一下。谢谢。问题就在代码附近。
BOARD_SIZE = 8
def under_attack(col, queens): # (col, queens) What is their meaning? What do I need to write it this field?
left = right = col
for r, c in reversed(queens): # What does reversed means in this loop? For what reson do we need r and c (their meaning is 0 by default?)?
left, right = left-1, right+1
if c in (left, col, right):
return True
return False
def solve(n):
if n == 0: return [[]]
smaller_solutions = solve(n-1) # For what reasons do we need to write smaller_solutions?
return [solution+[(n,i+1)] # What is solution (is it a function or what?)? What is value of i?
for i in range(BOARD_SIZE)
for solution in smaller_solutions
if not under_attack(i+1, solution)]
for answer in solve(BOARD_SIZE): print answer
谢谢!
答案 0 :(得分:8)
您的代码错误(剪切和粘贴错误?),但这是要点:
您需要一份可能的解决方案列表。每个解决方案都是皇后列表。每个皇后都是一个元组 - 一行(整数)和一列(整数)。例如,BOARD_SIZE=1
的解决方案是[[(1,1)]]
- 单个解决方案 - [(1,1)]
包含单个女王 - (1,1)
放置在第1行和第1列。
smaller_solutions
有8 BOARD_SIZE=8
,n=1
- [[(1,1)],[(1,2)],[(1,3)], [(1,4)],[(1,5)],[(1,6)],[(1,7)],[(1,8)]] - 一个皇后放在每一列第一行。
你理解递归吗?如果没有,请立即谷歌。
基本上,你首先将0个皇后添加到0号棋盘 - 这有一个简单的解决方案 - 没有皇后。然后你会找到将一个女王放在电路板第一排的解决方案。然后你寻找能够在第二排添加第二个女王的解决方案 - 某个地方没有受到攻击。等等。
def solve(n):
if n == 0: return [[]] # No RECURSION if n=0.
smaller_solutions = solve(n-1) # RECURSION!!!!!!!!!!!!!!
solutions = []
for solution in smaller_solutions:# I moved this around, so it makes more sense
for column in range(1,BOARD_SIZE+1): # I changed this, so it makes more sense
# try adding a new queen to row = n, column = column
if not under_attack(column , solution):
solutions.append(solution + [(n,column)])
return solutions
这解释了一般策略,但不是under_attack
。
under_attack
可以重写,以便更容易理解(对我,你和你的学生):
def under_attack(column, existing_queens):
# ASSUMES that row = len(existing_queens) + 1
row = len(existing_queens)+1
for queen in existing_queens:
r,c = queen
if r == row: return True # Check row
if c == column: return True # Check column
if (column-c) == (row-r): return True # Check left diagonal
if (column-c) == -(row-r): return True # Check right diagonal
return False
我的方法有点慢,但并不多。
旧的under_attack
基本相同,但它会加快速度。它以相反的顺序查看existing_queens
(因为它知道现有皇后的行位置将继续倒计时),跟踪左右对角线。
答案 1 :(得分:2)
BOARD_SIZE = 8
def under_attack(col, queens): # You do not need to fill in these fields. This is a helper function for the solve function.
left = right = col
for r, c in reversed(queens): # Reversing queens causes them to be iterated over in reverse order.
left, right = left-1, right+1
if c in (left, col, right):
return True
return False
def solve(n):
if n == 0: return [[]]
smaller_solutions = solve(n-1) # It appears that in solving this board, it solves all boards smaller than it in a recursive manner.
return [solution+[(n,i+1)] # This line appears to be in error. Have you run this code and verified that it runs correctly?
for i in range(BOARD_SIZE)
for solution in smaller_solutions
if not under_attack(i+1, solution)]
for answer in solve(BOARD_SIZE): print answer
答案 2 :(得分:0)
这是我的解决方案。它更容易理解和直接:
def under_attack(row, column, existing_queens):
if not len(existing_queens): return False
for queen in existing_queens:
if not len(queen):
continue
r,c = queen
if r == row: return True # Check row
if c == column: return True # Check column
if (column-c) == (row-r): return True # Check left diagonal
if (column-c) == -(row-r): return True # Check right diagonal
return False
def iter_solve(n):
solutions = None
for row in range(1, n+1):
# for each row, check all valid column
solutions = check(solutions, row, n)
return solutions
def check(solutions, row, n):
new_solutions = []
for column in range(1, n+1):
if not solutions or not len(solutions):
new_solutions.append([] + [(row, column)])
else:
for solution in solutions:
if not under_attack(row, column, solution):
new_solutions.append(solution + [(row, column)])
return new_solutions
答案 3 :(得分:0)
这是源程序,此代码的输出将在单独的文件名中生成为“queen.txt”
import json
import sys
BOARD_SIZE = 8
def under_attack(col, queens):
x = y = col
for r, c in reversed(queens):
x , y = x - 1, y + 1 #check for the prev queen location
if c in (x , col, y):
return True
return False
def solve(n): # n is the number of queens to be placed
if n == 0:
return [[]]
smaller_solutions = solve(n - 1)
return [solution+[(n,i+1)]
for i in xrange(BOARD_SIZE)
for solution in smaller_solutions
if not under_attack(i+1, solution)] #call the function
former, sys.stdout = sys.stdout, open('queen.txt','w')
for answer in solve(BOARD_SIZE):
print answer
results, sys.stdout = sys.stdout, former #former is used for ip & op
print json.dumps(answer) #dumps is used to write in json file
输出文件会像这样[(1,4),(2,2),(3,7),(4,3),(5,6), (6,8),(7,5),(8,1)] [(1,5),(2,2),(3,4),(4,7),(5,3),( 6, 8),(7,6),(8,1)] [(1,3),(2,5),(3,2),(4,8),(5,6),(6,4) ) (7,7),(8,1)]。 。 。 。 [(1,4),(2,7),(3,5),(4,2),(5,6),(6, 1),(7,3),(8,8)] [(1,5),(2,7),(3,2),(4,6),(5,3),(6,1) ) (7,4),(8,8)]