I'm trying to solve the classic n queen problem in python. Unfortunately the output was quite different with my expectation. I understood the back tracking algorithm but may be not clear on where I might make a mistake in writing the recursion. I tried 1.print one possible solution. 2. print all possible solutions. (here my solution was noted as a list of n, where value of list[i] is the selected column on the ith row)
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)
I'm expecting the n_queen_find1 to output a list of 4 element when n == 4, such as [1, 3, 0, 2]. In my recursion processes, the corrected answer was generated (as seen in the print). However, the function returned nothing. I added those print lines helping to debug, and found that I didn't understand why dfs not stopping and return when the first correct answer was created?
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
I slightly modified the n_queen_find1 to generate all possible solutions, but I could not explain the output as well.
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
Here is my test for n_queen_findall.It was not correct too. First, why the finalAnswers would append result when depth is not equal to n? Second, why there was a duplication in 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]]
Sorry for making the question that long.The cause of this problem may be quite simple.I'm junior in python and especially python backend.Maybe my understanding of python passing by reference was not correct? Really appreciate some guidance on this. Thanks very much in advance.