用障碍物计算从开始到结束的路径数

时间:2016-11-23 01:17:43

标签: python algorithm dynamic-programming

我正在尝试实现一个算法,该算法应该计算矩阵NxM的左下角到右上角的路径数。 我在一些网站上运行它,我上传了代码并运行了一堆测试用例,我看不出它正在运行哪些测试用例,所以我所知道的是它在某些测试用例中失败了。

问题的完整描述:

  

您将获得一个大小为N行×M列的单元格网格。机器人   位于左下角的单元格(第N-1行,第0列)。它可以移动   从细胞到细胞,但只到右边和顶部。有些细胞是   空的,机器人可以通过他们,但其他人不是和   机器人无法进入这样的细胞。机器人无法走出网格   边界。

     

机器人的目标是到达右上角的单元格(第0行,第M-1列)。都   开始和结束单元格始终为空。你需要计算   机器人从开始到结束可以采用的不同路径的数量。   仅计算访问空单元格并仅向右移动的路径   起来。

为此我正在做的是:

  1. 创建一个空网格NxM,用于存储该数字 从每个网格的起点S到网格[i] [j]的路径[i] [j]

  2. F(S)= 1#只有一种方法可以达到起点

  3. 对于每个单元格i,j我检查它是否被阻止,如果是,F(i,j)= 0

  4. 对于其余的单元格,我总结了两种可能的方法:F(i-1,j)+ F(i,j + 1)

  5. Python代码:

    def count_the_paths(grid):
        N = len(grid)
        M = len(grid[0])
    
        ways = [[None for _ in range(M)] for _ in range(N)] # Generate empty matrix to store the number of ways
        ways[N-1][0] = 1 # There's only 1 way to reach the starting point
    
        for row in range(N-1, -1, -1):
            for col in range(0, M):
                if grid[row][col] == 1: # Blocked cell
                    ways[row][col] = 0
                elif row != N-1 or col != 0: # If it's not the starting point
                    ways[row][col] = 0
                    if row < N-1:
                        ways[row][col] += ways[row+1][col]
                    if col > 0:
                        ways[row][col] += ways[row][col-1]
    
        return ways[0][M-1]
    

    例如,如果网格是:

    grid = [
        [0, 1, 0, 0, 0],
        [0, 0, 1, 0, 0],
        [0, 1, 1, 0, 0],
        [0, 1, 0, 0, 0],
        [0, 0, 0, 1, 0],
    ]
    

    ways矩阵是:

    ways = [
        [1, 0, 0, 1, 4], 
        [1, 1, 0, 1, 3], 
        [1, 0, 0, 1, 2], 
        [1, 0, 1, 1, 1], 
        [1, 1, 1, 0, 0]
    ]
    

    所以路径的数量是4,据我所知这是正确的。

    有没有人知道我错过了什么或做错了什么?

    更新: 正如@Tempux所说,我要存储路径数量的MODULO 1000003。

    所以我改变了我的代码:

    def count_the_paths(grid):
        N = len(grid)
        M = len(grid[0])
    
        ways = [[None for _ in range(M)] for _ in range(N)] # Generate empty matrix to store the number of ways
        ways[N-1][0] = 1 # There's only 1 way to reach the starting point
    
        for row in range(N-1, -1, -1):
            for col in range(0, M):
                if grid[row][col] == 1: # Blocked cell
                    ways[row][col] = 0
                elif row != N-1 or col != 0: # If it's not the starting point
                    ways[row][col] = 0
                    if row < N-1:
                        ways[row][col] += ways[row+1][col] % 1000003
                    if col > 0:
                        ways[row][col] += ways[row][col-1] % 1000003
    
        return ways[0][M-1]
    

    但是我说错误答案的错误仍然存​​在。

    更新2:

    根据User_Targaryen的建议,我改变了行

    if grid[row][col] == 1: # Blocked cell
    

    为:

    if grid[row][col] == "1": # Blocked cell
    

    但它仍然失败

    更新3:

    然后我的最后一次尝试(尝试使用char和整数)修正了Tempux建议的模块化添加:

    def count_the_paths(grid):
        N = len(grid)
        M = len(grid[0])
    
        ways = [[None for _ in range(M)] for _ in range(N)] # Generate empty matrix to store the number of ways
    
    
        ways[N-1][0] = 1 # There's only 1 way to reach the starting point
    
    
    
        for row in range(N-1, -1, -1):
            for col in range(0, M):
                if grid[row][col] == 1: # Blocked cell - also tried with char instead
    
    
                    ways[row][col] = 0
                elif row != N-1 or col != 0: # If it's not the starting point
    
    
                    ways[row][col] = 0
                    if row < N-1:
                        ways[row][col] += ways[row+1][col]
                        ways[row][col] %= 1000003                    
                    if col > 0:
                        ways[row][col] += ways[row][col-1]
                        ways[row][col] %= 1000003                    
    
        return ways[0][M-1]
    

    仍然失败

    最终更新[已解决] User_Targaryen是对的,他们的测试用例存在问题(他们是字符,而不是整数) 我收到了回复:

      

    嗨丹尼尔,

         

    非常感谢您写信给我们。有一个问题   一些问题的测试用例。它现在已修复。此外   在您的解决方案中,您应该更改检查单元格的方式   被占用与否。请注意,输入网格由0的字符串组成   他们不是数字。

         

    我们已经增加了您允许的尝试次数,以便您可以   提交更多。

         

    再次感谢

    感谢所有帮助过我的人。

2 个答案:

答案 0 :(得分:1)

路径数呈指数增长,这就是为什么在问题陈述中说:

  

编写一个方法,接受N,M和网格作为参数和   返回一个整数 - 不同路径的总数   机器人可以从开始到结束单元格,MODULO 1,000,003。

所以你应该保存number_of_paths % 1000003。这就是你得到错误答案的原因。

我不确定这是否会解决您提交中的所有问题,但

ways[row][col] += ways[row+1][col] % 1000003

不是计算模块化加法的正确方法。相反,您应该执行以下操作:

ways[row][col] += ways[row+1][col]
ways[row][col] %= 1000003

答案 1 :(得分:1)

查看问题陈述,由于缺乏解决方案中的错误信息,我认为输入有点像:

grid = ['01100','00010','01010','01000','00010']

因为它说:输入网格将包含N个字符串,每个字符串包含M个字符 - 0或1

更改代码中的以下行会产生10个更多点:

if grid[row][col] == '1': # Blocked cell

修改:您可以找到一个非常相似的问题here。提交您的解决方案以检查您的基本逻辑是否正确。

这是我接受的 CodeChef 问题的解决方案:

def numWays(m,n,p):
  grid = [[0 for _ in range(n)] for _ in range(m)]
  ways = [[0 for _ in range(n)] for _ in range(m)]
  mod = 1000000007
  i = 0
  while i<p:
    i=i+1
    x,y = map(int, raw_input().split())
    grid[x-1][y-1]=1

  if grid[0][0]==1 or grid[m-1][n-1]==1:
    return 0

  ways[0][0]=1

  i=0
  ways[0][0] = 1
  while i<m:
    j = 0
    while j<n:
      if grid[i][j]==0:
        if i-1>=0 and j-1>=0:
          ways[i][j] = (ways[i][j-1] + ways[i-1][j]) % mod
        elif i-1>=0:
          ways[i][j] = ways[i-1][j]
        elif j-1>=0:
          ways[i][j] = ways[i][j-1]
      j=j+1
    i = i+1

  return ways[m-1][n-1]

def main():
  m,n,p = map(int, raw_input().split())
  print numWays(m,n,p)

main()