簡體   English   中英

跟蹤在 Python 中調用了遞歸 function 的次數

[英]Keep track of how many times a recursive function has been called in Python

我有一段 Python 代碼,它實現了一個遞歸回溯算法,用於解決國際象棋中著名的 N 皇后問題。

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 ,output 是

here 1
here 2
here 3
here 3
here 4
here 2
here 3
here 4
here 5

這表明我的嘗試是不正確的。 function 被調用了 9 次,但最后計數器變量為 5。

整數是不可變的,因此當您執行counter += 1時,您會創建一個新數字,例如從 1 到 2,並且 2 現在綁定到名稱counter 因此,當您處於深度 2 並調用 function 兩次時,兩個調用都會將 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,如果你再次調用 function,它將從那里繼續遞增。

骯臟的黑客:使用 Python 中的默認 arguments 在 function 調用之間共享的事實:

def Backtrack(board, col, counter = [0]):

  counter[0]+=1
  print('here', counter[0])

正確的解決方案:將您的方法包含在 class 中:

class Board():
    counter = 0

    def Backtrack(self, board, col):

        self.counter+=1
        print('here', self.counter)

后來這樣稱呼:

Board().Backtrack(board, 0)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM