python中的递归和多维矩阵

时间:2017-09-05 08:14:52

标签: python recursion memoization

这是着名的路径计数问题,我正在尝试使用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

2 个答案:

答案 0 :(得分:0)

我相信你试图解决this problem

如果是这种情况,那么你是正确的,用递归来解决是明智的。

如果您将网格的每个角想象为一个节点,那么您需要一个递归函数,它只需要一个(x, y)节点的参数。在函数中,首先需要检查它被调用的位置是否是网格的右下顶点。如果是,则该函数向path count添加一个(当路径到达此角落时路径已完成)然后返回。否则,此函数只调用两个本身(这是递归),一个调用right(所以y+1),一个调用leftx+1)。一个额外的步骤是检查坐标是否在网格中,然后将它们作为底行中间的节点调用,例如,不应该调用它下面的节点,因为它将离开网格。

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

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

如果你已经完成了,我们也可以从右下角到左上角进行编码。最后一件事是如果你使用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网格。希望这有帮助!

答案 1 :(得分:0)

您在算法实现中遇到了一些错误。如果您使用递归方法,则不必使用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代表顶点数量,因此2不是3而是2x2网格。由于此代码使用纯递归,因此速度非常慢。如果你想使用你的记忆方法,你必须修改你的代码:

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网格的参数来调用它。由于已经计算的路径的缓存,此代码更快。