【发布时间】:2017-11-19 23:56:30
【问题描述】:
我正在尝试解决 python 中的经典 n Queen 问题。不幸的是,输出与我的预期完全不同。我了解回溯算法,但可能不清楚在编写递归时可能会出错的地方。我尝试了 1.print 一种可能的解决方案。 2. 打印所有可能的解决方案。 (这里我的解决方案被记为 n 的列表,其中 list[i] 的值是第 i 行上的选定列)
def n_queen_find1(n):
answer = [-1] * n
def dfs(depth,answer):
if depth == n:
print ("cur valid answer is ",answer)
return answer
else:
for colNum in range(n): # check every col at cur depth
if is_safe(depth,colNum,answer):
answer[depth] = colNum
print ("now the answer is ", answer)
print ("now depth move to ", depth + 1)
dfs(depth + 1,answer)
def is_safe(i,j,answer_cur):
# given current queen placement , could we place the ith queen (at row i) at the col j
for prerow in range(i):
if answer_cur[prerow] == j or abs(prerow - i) == abs(answer_cur[prerow] - j):
return False
return True
return dfs(0,answer)
我希望 n_queen_find1 在 n == 4 时输出 4 个元素的列表,例如 [1, 3, 0, 2]。在我的递归过程中,生成了正确的答案(如打印中所示)。但是,该函数什么也没返回。我添加了那些有助于调试的打印行,发现我不明白为什么在创建第一个正确答案时 dfs 没有停止并返回?
trial1 = n_queen_find1(4)
print trial1
('now the answer is ', [0, -1, -1, -1])
('now depth move to ', 1)
('now the answer is ', [0, 2, -1, -1])
('now depth move to ', 2)
('now the answer is ', [0, 3, -1, -1])
('now depth move to ', 2)
('now the answer is ', [0, 3, 1, -1])
('now depth move to ', 3)
('now the answer is ', [1, 3, 1, -1])
('now depth move to ', 1)
('now the answer is ', [1, 3, 1, -1])
('now depth move to ', 2)
('now the answer is ', [1, 3, 0, -1])
('now depth move to ', 3)
('now the answer is ', [1, 3, 0, 2])
('now depth move to ', 4)
('cur valid answer is ', [1, 3, 0, 2])
('now the answer is ', [2, 3, 0, 2])
('now depth move to ', 1)
('now the answer is ', [2, 0, 0, 2])
('now depth move to ', 2)
('now the answer is ', [2, 0, 3, 2])
('now depth move to ', 3)
('now the answer is ', [2, 0, 3, 1])
('now depth move to ', 4)
('cur valid answer is ', [2, 0, 3, 1])
('now the answer is ', [3, 0, 3, 1])
('now depth move to ', 1)
('now the answer is ', [3, 0, 3, 1])
('now depth move to ', 2)
('now the answer is ', [3, 0, 2, 1])
('now depth move to ', 3)
('now the answer is ', [3, 1, 2, 1])
('now depth move to ', 2)
None
我稍微修改了 n_queen_find1 以生成所有可能的解决方案,但我也无法解释输出。
def n_queen_findall(n):
answer = [-1] * n
finalAnswer = []
def dfs(depth,answer,finalAnswer):
if depth == n:
print ("cur valid answer is ",answer)
finalAnswer.append(answer)
print ("after appending final answer is ", finalAnswer)
return
else:
for colNum in range(n): # check every col at cur depth
if is_safe(depth,colNum,answer):
answer[depth] = colNum
print ("now the answer is ", answer)
print ("now depth move to ", depth + 1)
dfs(depth + 1,answer,finalAnswer)
def is_safe(i,j,answer_cur):
# given current queen placement , could we place the ith queen (at row i) at the col j
for prerow in range(i):
if answer_cur[prerow] == j or abs(prerow - i) == abs(answer_cur[prerow] - j):
return False
return True
dfs(0,answer,finalAnswer)
return finalAnswer
这是我对 n_queen_findall 的测试。它也不正确。首先,当深度不等于 n 时,为什么 finalAnswers 会附加结果?二、为什么finalAnswer有重复?
trial2 = n_queen_findall(4)
print trial2
('now the answer is ', [0, -1, -1, -1])
('now depth move to ', 1)
('now the answer is ', [0, 2, -1, -1])
('now depth move to ', 2)
('now the answer is ', [0, 3, -1, -1])
('now depth move to ', 2)
('now the answer is ', [0, 3, 1, -1])
('now depth move to ', 3)
('now the answer is ', [1, 3, 1, -1])
('now depth move to ', 1)
('now the answer is ', [1, 3, 1, -1])
('now depth move to ', 2)
('now the answer is ', [1, 3, 0, -1])
('now depth move to ', 3)
('now the answer is ', [1, 3, 0, 2])
('now depth move to ', 4)
('cur valid answer is ', [1, 3, 0, 2])
('now the final answer is ', [])
('now the answer is ', [2, 3, 0, 2])
('now depth move to ', 1)
('now the answer is ', [2, 0, 0, 2])
('now depth move to ', 2)
('now the answer is ', [2, 0, 3, 2])
('now depth move to ', 3)
('now the answer is ', [2, 0, 3, 1])
('now depth move to ', 4)
('cur valid answer is ', [2, 0, 3, 1])
('now the final answer is ', [[2, 0, 3, 1]])
('now the answer is ', [3, 0, 3, 1])
('now depth move to ', 1)
('now the answer is ', [3, 0, 3, 1])
('now depth move to ', 2)
('now the answer is ', [3, 0, 2, 1])
('now depth move to ', 3)
('now the answer is ', [3, 1, 2, 1])
('now depth move to ', 2)
[[3, 1, 2, 1], [3, 1, 2, 1]]
抱歉把问题问的这么长。这个问题的原因可能很简单。我是python的初级,尤其是python后端。也许我对python通过引用传递的理解不正确?非常感谢对此的一些指导。提前非常感谢。
【问题讨论】:
-
感谢您的评论。 if 条件中的
abs(prerow - i) == abs(answer_cur[prerow] - j)用于检查对角线。在is_safe函数中,检查了两件事,1) 列冲突 2) 对角线冲突。默认情况下,它不检查行,因为它们在不同的行中。