递归Python方法

时间:2015-08-07 22:30:25

标签: python recursion

我正在编写一个程序来解决一种方形拼图,它通过蛮力尝试每个可能的碎片组合,直到它找到有用的东西。

董事会看起来像这样

1 - 2 - 3

4 - 5 - 6

7 - 8 - 9

我从一堆嵌套for循环开始,

 for a in range(1,10):
     #create piece
     #than test it
     if checkPiece(pieceNumber):
          for b in range (1,10):

......依此类推九次。

然后我意识到同样的事情可以通过两个递归函数来完成,这将尝试一个片段,而不是正确调用第二个函数,然后成功引用第一个函数!

def Solve():
    global level;
    global AvailableNumbers;
    if level == 10:
        Solved();
    for i in AvailableNumbers:
        print "We are %d far into level %d with fct. ONE" %(i,level);
        clearList(level);
        AvailableNumbers.remove(i)
        spot[level] = pieces[i];
        result = checkPiece(level)
        print result
        if result == True:
            level += 1
            Solve2();
        else:
            AvailableNumbers.append(i);
            spot[level] = [];

第二个功能与第一个功能相同(除了它调用第一个功能)。

此代码的问题在于它会过早地结束,并且永远不会调用Solved()。

我怀疑当一个方法被调用时,它可能会覆盖该方法的任何先前活动(从而结束我的递归梦),但不能确定我的代码中是否存在其他错误。

有没有办法在for循环中递归调用for循环,

(不是{}代表{} {}代表{}代表{for {for {for {}}}}}

无需全部写出来?

感谢您阅读所有这些内容。 任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:0)

我会尝试以下内容:

def Solve(level, available_numbers):
  if level == 10:
    return spot
  for i in available_numbers:
    print "We are %d far into level %d with fct. ONE" %(i,level)
    clearList(level)
    # Note you are not removing i from available_numbers yet
    spot[level] = pieces[i]
    result = checkPiece(level)
    print result
    if result == True:
      available_number = available_number.remove(i)
      Solve(level + 1, available_number)  # tail recursion!

    # note no need for your else statement. We haven't removed i from our list yet,
    # and we can just overwrite spot[level] on the next pass.

我不能在没有其余代码的情况下测试这个,但是这个想法基本上是用递减的数字池调用Solve函数的递归迭代,直到你得到一个有效的点的每个数字。我假设spot是你的解决方案向量,所以在最后,我们返回spot,它将链传递回顶部并输出。如果spot无法全局访问,您可以将其添加为函数的另一个输入,并在进行递归调用时将其传递给该行。

如果您对真正潜入递归感兴趣,请查看麻省理工学院的恒星Structure and Interpretation of Computer Programs课程。该链接免费提供完整的书籍。我一直在Racket中完成它,我也不介意推荐。

编辑:从我们在评论中的讨论中,听起来每个级别的递归需要检查前一级别是否返回了有效的解决方案,或者只是在没有找到解决方案的情况下停止,然后通过有效的解决方案或相应地继续进行其for循环的下一次迭代。也许是这样的?

def Solve(level, nums, spot):
  if level = 10:  # maybe check if nums = [] for an arbitrary number of levels?
    return (spot, True)  # pass back solution and Boolean saying it's solved
  for i in nums:
    # place your next piece
    result = checkPiece(level)
    if result:  # no need for the "== True" bit
      nums = nums.remove(i)
      spot, solved = Solve(level + 1, nums, spot)  # recursive call
      if solved:  # valid solution reached?
        return (spot, solved)  # pass new solution up the chain
      # else continue to the next iteration of the for loop
  return (spot, False)  # reach this if no valid solution is found at this level

关键的变化是,除了传递一个告诉我们是否已达到有效解决方案的布尔值之外,现在我们明确地将更新的解决方案向量传递回链。您还可以检查解决方案在每个级别是否有效,但这似乎效率较低。如果我们在任何级别的for循环都耗尽,我们会返回solved = False,这会让我们陷入下一个更高级别的for循环的下一次迭代。如果这可以让你到达目的地,请告诉我。