网格中的机器人-如何获取所有可能的路径

问题描述

我正在尝试解决此问题:

一个带有r行和c列的网格。坐在左上方单元格中的机器人只能向左右两个方向移动。但是必须避免某些单元格,并且机器人无法踩踏它们。从左上角到右下角找到机器人的路径。

这个问题专门要求一条路,这似乎很简单:

将网格设为boolean[][],我拥有的伪代码

List<String> path = new ArrayList<String>()
boolean found = false

void getPath(r,c){
    if (!found) {

      if ( (r or c is outofbounds) || (!grid[r][c]) )
          return

      if (r==0 AND c==0)  // we reached
           found = true

      getPath(r-1,c)
      getPath(r,c-1)

      String cell = "(" + r + "," + c + ")"
      path.add(cell)

    }    
}

尽管我想知道如何获得所有可能的路径(不仅是计数,而且还有路径值)。请注意,它具有r行和c列,因此它不是nxn网格。我试图考虑一个DP /递归解决方案,但无法提出任何建议并陷入困境。很难想到递归有两种方式。

有指针吗?此外,对于如何“思考”此类问题的任何常规帮助也将不胜感激:)。

解决方法

有指针吗?此外,对于如何“思考”此类问题的任何常规帮助也将不胜感激:)。

解决方法:

  1. 精神上构造问题的图形G。在这种情况下,顶点是网格中的单元,并在存在有效的机器人移动的位置创建有向边。
  2. 搜索G的属性。在这种情况下,G是 DAG (有向无环图)。
  3. 使用此类属性提出解决方案。在这种情况下(G是DAG),通常使用拓扑排序动态编程查找有效路径的数量。

实际上,您不需要构造图,因为边缘集非常清晰,也可以进行拓扑排序,因为矩阵的常规迭代(增量行索引和列增量索引)是此隐式图的拓扑排序。

可以通过在每个单元格[x][y]中存储从[0][0][x][y]的有效路径的数量并检查下一步要移动的位置来解决动态编程部分。
重复发生
1

计算后,答案存储在dp[n - 1][m - 1]中,其中n是行数,m是列数。总体运行时间为O(nm)

如何查找所有可能的有效路径:
通常的回溯都是可行的,我们可以通过早期修剪来加快速度。实际上,如果我们计算dp矩阵,然后从像元[n - 1][m - 1]进行回溯,则只要机器人进入dp值为零的像元,就可以避免无效路径。

具有dp矩阵的Python代码是预先计算的:

n,m = 3,4
bad = [[False,False,False],[ True,True,[False,False]]
dp = [[1,1,1],[0,2],3]]

paths = []
curpath = []
def getPath(r,c):
    if dp[r][c] == 0 or r < 0 or c < 0:
        return
    curpath.append((r,c))
    if r == 0 and c == 0:
        paths.append(list(reversed(curpath)))
    getPath(r - 1,c)
    getPath(r,c - 1)
    curpath.pop()

getPath(n - 1,m - 1)
print(paths)

# valid paths are [[(0,0),(0,1),2),3),(1,(2,3)],#                  [(0,3)]]

请注意,该代码与您的代码非常相似,因此需要将所有有效路径存储在一起,并注意附加列表是curpath的副本,以免最后出现一个空列表。

运行时间:O((n + m) * (amount of valid paths)),因为模拟的机器人移动属于有效路径,或者第一步是使用远见(dp)检测到的无效路径。警告:由于有效路径的数量可以为2,因此此方法是指数的。