【问题标题】:recursion and multi dimension matrix in pythonpython中的递归和多维矩阵
【发布时间】:2018-02-13 11:03:56
【问题描述】:

这是著名的路径计数问题,我正在尝试使用 memoization 来解决它。 启发我!

def pathCounter(a,b):
    matrix = [[0 for i in xrange(a)] for i in xrange(b)]

    if a==0 or b==0:
        return 1

    if matrix[a][b]:
        return matrix[a][b]

    print matrix[a][b]
    matrix[a][b]=pathCounter(a,b-1)+pathCounter(a-1,b)

    return matrix[2][2] 

if __name__=='__main__':
    k=pathCounter(2,2)
    print k

【问题讨论】:

  • 你的具体问题是什么?
  • 第十五题。我只想在python中解决它,需要在python中学习递归和其他概念

标签: python recursion memoization


【解决方案1】:

相信您正在努力解决this problem

如果是这样,那么你是正确的,用递归解决是明智的。

如果您将网格的每个角想象成一个节点,那么您想要一个递归函数,它只接受它在(x, y) 处的节点的参数。在函数中,它首先需要检查它被调用的位置是否是网格的右下角顶点。如果是,该函数在path count 上加一(因为路径在到达该角时就结束了)然后返回。否则,这个函数只会再调用两个自身(这是递归),一个调用它的right(所以y+1),一个调用它的leftx+1)。一个额外的步骤是在将坐标调用为底行中间的节点之前检查坐标是否在网格中,例如不应调用其下方的节点,因为那样会脱离网格。

现在您已经定义了递归函数,您现在需要做的就是声明一个变量来存储path count。并从坐标(0,0)调用递归函数。

但是,我相信您已经看到,此解决方案并未在合理的时间内完成,因此您有必要使用 memoization - 通过缓存节点来加速它,以便不计算相同的路径部分两次。

如果像您所做的那样,我们从右下角向上到左上角工作,它还会使编码变得更加简单。最后一件事是,如果您使用dictionary,那么代码会变得更清晰。

最终代码应如下所示:

cache = {}

def pathCounter(x, y):
   if x == 0 or y == 0:
       return 1
   if (x,y) in cache:
      return cache[(x,y)]

   cache[(x,y)] = pathCounter(x, y-1) + pathCounter(x-1, y)
   return cache[(x,y)]

print(pathCounter(2,2))

这给出了6 的预期结果。

我会让你做20x20 网格。希望这会有所帮助!

【讨论】:

    【解决方案2】:

    您在实现算法时犯了一些错误。如果您使用递归方法,则不必使用grid,因为实际上您需要任何存储的数据。您只需要从当前位置返回两个可能的子路径 - 就是这样!因此,您需要对代码的主要思想进行一些更改。

    我尝试尽可能多地保留您的原始代码,但仍使其正常工作:

    def pathCounterNaive(width, height, startX = 0, startY = 0):
        if startX >= width or startY >= height:
           return 0
    
       if startX == width-1 and startY == height-1:
          return 1
    
       return pathCounter(width,height, startX+1, startY) + pathCounter(width,height, startX, startY+1)
    
    slowK=pathCounterNaive(3,3)
    print(slowK)
    

    请记住,参数widthheight 表示顶点的数量,因此对于2x2 网格不是2 而是3。由于此代码使用纯递归,因此速度非常慢。如果你想使用你的记忆方法,你必须像这样修改你的代码:

    import numpy as np
    def pathCounter(width, height):
        grid = np.zeros((height+1, width+1))
        def pathCounterInternal(x, y):
            if x==0 or y==0:
                return 1
    
            grid[x, y] = pathCounterInternal(x,y-1)+pathCounterInternal(x-1,y)
    
            return grid[x, y]
    
        grid[width, height] = pathCounterInternal(width, height)
        return grid[width, height]
    
    k=pathCounter(2,2)
    print(k)
    

    在这里,您必须使用2 作为2x2 网格的参数来调用它。由于缓存了已计算的路径,此代码要快得多。

    【讨论】:

    • OP 要求使用memoization 来解决它,这对于它在合理的时间内完成更大的网格大小是必要的......
    猜你喜欢
    • 2019-11-13
    • 2021-09-27
    • 1970-01-01
    • 2014-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-26
    相关资源
    最近更新 更多