寻路 Python 算法回溯

Posted

技术标签:

【中文标题】寻路 Python 算法回溯【英文标题】:Pathfinding Python Algorithm Backtracking 【发布时间】:2020-12-08 01:11:49 【问题描述】:

给定一个像board 这样的矩阵,我想找到可以让我找到更多数字1's 的路径,因为我知道我只能上(n+1) 和右(m+1)。我正在尝试使用回溯解决方案,并且我设法知道我可以在最佳路径上找到多少 1's,但我无法弄清楚如何打印最佳路径的坐标。

board=[[0,0,0,0,1,0],
       [0,1,0,1,0,0],
       [0,0,0,1,0,1],
       [0,0,1,0,0,1],
       [1,0,0,0,1,0]]

def findPath(board,n,m):
    noo=0
    if board[n][m]>0:
        noo+=1
    if n==len(board)-1 and m==len(board[0])-1:
        return noo
    if n==len(board)-1:
        noo+=findPath(board,n,m+1)
    elif m==len(board[0])-1:
        noo+=findPath(board,n+1,m)
    else:
        noo+=max(findPath(board,n,m+1),findPath(board,n+1,m))
    return noo

print(findPath(board,0,0))

我应该如何或在哪里实现print(n,m) 以打印最佳路径的每个网格的坐标

已编辑

想出了这个解决方案

def path(board,x,y,xl,yl,sol,index,paths):
    sol.append([x,y])
    solaux=sol
    if x==0 and y==0:
        pass
    if board[x][y]>0:
        sol[0]+=1
    if x==xl-1 and y==yl-1:
        paths.append(sol)
        print(sol)
        return paths
    if x==xl-1:
        path(board,x,y+1,len(board),len(board[0]),sol,index,paths)
    elif y==yl-1:
        path(board,x+1,y,len(board),len(board[0]),sol,index,paths)
    else:
        index= len(sol)
        auxnoo= sol[0]
        path(board,x,y+1,len(board),len(board[0]),sol,index,paths)
        sol = sol[0:index]
        sol[0]=auxnoo
        path(board,x+1,y,len(board),len(board[0]),sol,index,paths)
    return paths

【问题讨论】:

对明显的拼写和语法/标点错误的编辑旨在使您的问题更易于阅读和更容易通过搜索找到。请不要撤消那些积极尝试以建设性方式编辑您的问题来帮助您和他人的成员的工作 我的坏可能点击了错误的按钮 【参考方案1】:

起初,您的实现效率非常低,因为您多次为单个单元格执行findPath。例如,如果您有 2x2 网格,则单元格 (1, 1) 将被访问两次:

(1, 0) -- path 2 --> (1, 1)
   ^                   ^
   | path 2            | path 1
   |                   |
(0, 0) -- path 1 --> (0, 1)

所以让我们记住每个单元格的noo 值:

# noo[i][j] == None value means value for cell wasn't calculated before.
# Otherwise noo[i][j] it means calculated answer for cell.
noo=[[None for i in range W] for j in range H]

def findPath(board,n,m):
    if noo[n][m] is not None:
        return noo[n][m]
    noo[n][m] = board[n][m]
    if n==len(board)-1 and m==len(board[0])-1:
        return noo[n][m]
    if n==len(board)-1:
        noo[n][m]+=findPath(board,n,m+1)
    elif m==len(board[0])-1:
        noo[n][m]+=findPath(board,n+1,m)
    else:
        noo[n][m]+=max(findPath(board,n,m+1),findPath(board,n+1,m))
    return noo[n][m]

print(findPath(board,0,0))

我应该如何或在哪里实现 print(n,m) 以打印最佳路径的每个网格的坐标

其次,没有简单的方法将print(n,m) 放入给定的代码中,因为对于给定的单元格,我们不知道它是否属于任何最佳路径。只有当我们回到单元格 (0, 0) 时,我们才能确定它。

但现在我们有二维数组noo:如果noo[i][j] 包含值x,那么最佳方向将是相对于单元格(i, j) 位于下一个右侧或使用noo[i1][j1] >= x - 1 向上单元格(i1, j1)noo[i1][j1] 可以等于x,如果board[i][j] == 0x - 1,如果board[i][j] == 1)。让我们实现最优路径打印机:

def printOptimalPath(n, m):
    print(n, m)
    if n < len(board)-1 and noo[n + 1][m] == noo[n][m] - board[n][m]:
        printOptimalPath(n + 1, m)
    elif m < len(board[0])-1 and noo[n][m + 1] == noo[n][m] - board[n][m]:
        printOptimalPath(n, m + 1)

# Usage
printOptimalPath(0, 0)

请注意,如果noo[n+1][m]noo[n][m+1] 都满足上述条件,则意味着存在多个最优路径,您可以选择任意方向。

【讨论】:

以上是关于寻路 Python 算法回溯的主要内容,如果未能解决你的问题,请参考以下文章

回溯算法 python

Python回溯算法

python中数独的回溯算法

leetcode 46 Permutations Python 实现(回溯算法)

Python数独回溯

leetcode-46. 全排列--回溯算法--python