我有一段 Python 代碼,它實作了一個遞回回溯演算法,用于解決國際象棋中著名的 N-Queens 問題。
def Backtrack(board, col):
if col >= N:
return True
for i in range(N):
if (ld[i - col N - 1] != 1 and rd[i col] != 1) and cl[i] != 1:
board[i][col] = 1
ld[i - col N - 1] = rd[i col] = cl[i] = 1
if Backtrack(board, col 1):
return True
board[i][col] = 0 # Backtrack
ld[i - col N - 1] = rd[i col] = cl[i] = 0
return False
在哪里
ld = np.zeros(2*N - 1, dtype=int)
rd = np.zeros(2*N - 1, dtype=int)
cl = np.zeros(N, dtype=int)
board = np.zeros((N, N), dtype=int)
問題:
我想跟蹤呼叫遞回回溯演算法的次數。
我的嘗試:
我在代碼中添加了一個計數器變數,這樣
def Backtrack(board, col, counter):
counter = 1
print('here', counter)
if col >= N:
return True
for i in range(N):
if (ld[i - col N - 1] != 1 and rd[i col] != 1) and cl[i] != 1:
board[i][col] = 1
ld[i - col N - 1] = rd[i col] = cl[i] = 1
if Backtrack(board, col 1, counter):
return True
board[i][col] = 0 # Backtrack
ld[i - col N - 1] = rd[i col] = cl[i] = 0
return False
但是對于N = 4,輸出是
here 1
here 2
here 3
here 3
here 4
here 2
here 3
here 4
here 5
這表明我的嘗試是不正確的。該函式被呼叫了 9 次,但最后計數器變數為 5。
uj5u.com熱心網友回復:
整數是不可變的,所以當你這樣做時counter = 1,你會創建一個新的數字,比如從 1 到 2,并且 2 現在系結到 name counter。因此,當您處于深度 2 并呼叫該函式兩次時,兩個呼叫都會將 2 遞增到它們自己的 3。在 python 中,您不是通過變數傳遞,而是通過名稱傳遞,所以這counter并不是指同一件事電話。
你想要的是一個可變或全域變數。例如
# or a class implementation equivalent
counter = 0
def backtrack(board, col):
global counter
counter = 1
# the rest
但是這樣counter每次你想重新啟動演算法時都需要重置為 0。因此,我認為最好這樣做
def backtrack(board, col, counter=None):
if not counter:
counter = [0]
counter[0] = 1
# the rest of your function
這樣做要非常小心backtrack(board, col, counter=[0]),因為counter只會將串列初始化一次。在你解決之后,比如 N=4,它的值為 9,如果你再次呼叫這個函式,它會從那里繼續遞增。
uj5u.com熱心網友回復:
Dirty hack: 使用 Python 中的默認引數在函式呼叫之間共享的事實:
def Backtrack(board, col, counter = [0]):
counter[0] =1
print('here', counter[0])
正確的解決方案: 將您的方法包含在一個類中:
class Board():
counter = 0
def Backtrack(self, board, col):
self.counter =1
print('here', self.counter)
后來這樣稱呼:
Board().Backtrack(board, 0)
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/413742.html
標籤:
