繁体   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