这是着名的路径计数问题,我正在尝试使用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
答案 0 :(得分:0)
如果是这种情况,那么你是正确的,用递归来解决是明智的。
如果您将网格的每个角想象为一个节点,那么您需要一个递归函数,它只需要一个(x, y)
节点的参数。在函数中,首先需要检查它被调用的位置是否是网格的右下顶点。如果是,则该函数向path count
添加一个(当路径到达此角落时路径已完成)然后返回。否则,此函数只调用两个本身(这是递归),一个调用right
(所以y+1
),一个调用left
(x+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)
请注意,参数width
和height
代表顶点数量,因此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
网格的参数来调用它。由于已经计算的路径的缓存,此代码更快。