Python 计算通过网格的可能路径数
在N*M网格的左上角有一个机器人。机器人可以上、下、左、右移动,但在每次移动中不能访问同一个细胞超过一次。我如何找到机器人到达右下角的方式总数 (机器人不需要访问每个单元,路径才有效) 我认为这有一个递归的解决方案,但我不知怎么搞不懂 以下是到目前为止我得到的信息:Python 计算通过网格的可能路径数,python,recursion,graph,Python,Recursion,Graph,在N*M网格的左上角有一个机器人。机器人可以上、下、左、右移动,但在每次移动中不能访问同一个细胞超过一次。我如何找到机器人到达右下角的方式总数 (机器人不需要访问每个单元,路径才有效) 我认为这有一个递归的解决方案,但我不知怎么搞不懂 以下是到目前为止我得到的信息: def initialize(row, cols): grid = [ [ 0 for c in range(cols) ] for r in range(rows) ] pos_r, pos_c = 0, 0
def initialize(row, cols):
grid = [ [ 0 for c in range(cols) ] for r in range(rows) ]
pos_r, pos_c = 0, 0
grid[pos_r][pos_c] = 1 # set start cell as visited
dst_x, dst_y = len(grid)-1, len(grid[0])-1 # coords of bottom-right corner
print move_robot(grid, dst_x, dst_y, pos_r, pos_c)
def move_robot(grid, dst_x, dst_y, pos_r, pos_c, prev_r=None, prev_c=None):
num_ways = 0
if reached_dst(dst_x, dst_y, pos_r, pos_c):
undo_move(grid, pos_r, pos_c)
undo_move(grid, prev_r, prev_c)
return 1
else:
moves = get_moves(grid, pos_r, pos_c)
if len(moves) == 0:
undo_move(grid, prev_r, prev_c)
return 0
for move in moves:
prev_r = pos_r
prev_c = pos_c
pos_r = move[0]
pos_c = move[1]
update_grid(grid, pos_r, pos_c)
num_ways += move_robot(grid, dst_x, dst_y, pos_r, pos_c, prev_r, prev_c)
return num_ways
if __name__ == '__main__':
initialize(4, 4)
为了简洁起见,我省略了一些函数定义。Get_moves检索所有合法移动,检查每个移动是否仍在板上,以及单元格是否已被访问。Update_grid将指定的单元格设置为“1”,表示已访问。Undo_move则相反,将指定的单元格设置为“0”
对于最简单的情况(2*2网格),我得到了正确的答案,但是对于较大的网格,输出总是太低。我的代码有什么问题,有没有一种更简单的方法可以做到这一点?递归非常简单,但在递归时要小心创建矩阵的副本,以获得良好的结果:
对我来说,听起来像是一个动态规划问题;将每个单元格的访问方式与相邻单元格的访问方式相加。是的,我理解这个概念(至少我认为我理解),但在将其转换为代码时遇到困难。@MartijnPieters不是重复的。这个机器人可以向各个方向移动。好的,我明白你的意思。我很惊讶我还没有找到一个傻瓜。是我能为你搜索的最接近的了。谢谢,这很有意义!我一直在努力解决如何撤销对原始网格的递归调用的影响。
from copy import copy, deepcopy
def calc(i, j, mat):
if i < 0 or j < 0 or i >= len(mat) or j >= len(mat[0]):
return 0 # out of borders
elif mat[i][j] == 1:
return 0 # this cell has already been visited
elif i == len(mat)-1 and j == len(mat[0])-1:
return 1 # reached destination (last cell)
else:
mat[i][j] = 1 # mark as visited
# create copies of the matrix for the recursion calls
m1 = deepcopy(mat)
m2 = deepcopy(mat)
m3 = deepcopy(mat)
m4 = deepcopy(mat)
# return the sum of results of the calls to the cells:
# down + up + right + left
return calc(i+1, j, m1) + calc(i-1, j, m2) + calc(i, j+1, m3) + calc(i, j-1, m4)
def do_the_robot_thing(m, n):
# an un-visited cell will be marked with "0"
mat = [[0]*n for x in xrange(m)]
return calc(0, 0, mat)
print(do_the_robot_thing(3, 3))
12