Python 求N*N矩阵的最大代价路径,从[0,0]到[N-1,N-1],且在一个方向上具有性能

Python 求N*N矩阵的最大代价路径,从[0,0]到[N-1,N-1],且在一个方向上具有性能,python,matrix,dynamic-programming,Python,Matrix,Dynamic Programming,例如,给定一个成本矩阵,我不仅需要知道从[0,0]到[N-1,N-1]的最大总成本,还需要知道我使用此最佳路径所做的移动。同时,水平移动比垂直移动具有更高的优先级 |1 | 2 | 3| |2 |-8 | 4| |3 | 4 | 6| 我知道这可以通过动态规划来解决。但是,如何记录需要进行的移动 在这种情况下,两条路径:(右,右,下,下)将给出与(下,下,右,右)完全相同的总成本,最佳路径将仅为(右,右,下,下) 为了说明这一点,我的问题是,如何找出最优路径的所有运动 def optimal(m

例如,给定一个成本矩阵,我不仅需要知道从[0,0]到[N-1,N-1]的最大总成本,还需要知道我使用此最佳路径所做的移动。同时,水平移动比垂直移动具有更高的优先级

|1 | 2 | 3|

|2 |-8 | 4|

|3 | 4 | 6|

我知道这可以通过动态规划来解决。但是,如何记录需要进行的移动

在这种情况下,两条路径:(右,右,下,下)将给出与(下,下,右,右)完全相同的总成本,最佳路径将仅为(右,右,下,下)

为了说明这一点,我的问题是,如何找出最优路径的所有运动

def optimal(mat):
    dim = len(mat)
    cost = [[0]*dim for i in range(dim)]
    path = []
    if mat[0][1]>=mat[1][0]:
        path.append('r')
    else:
        path.append('d')
    cost[0][0] = mat[0][0]
    for i in range(1,dim):
        cost[i][0] = mat[i][0] + cost[i - 1][0]
    for j in range(1,dim):
        cost[0][j] = mat[0][j] + cost[0][j - 1]
    for i in range(1, dim):
        for j in range(1, dim):
            if cost[i-1][j] >=  cost[i][j-1]:
                cost[i][j] = cost[i-1][j] + mat[i][j]
            else:
                cost[i][j] = cost[i][j-1] + mat[i][j]
    print(cost[dim-1][dim-1])
    print(path)

从以动态编程方式创建结构开始。首先求解矩阵的底部和右边缘,然后重用这些结果来求解越来越多的问题,直到您知道每个字段的最大成本和方向

然后从左上角遍历矩阵,以收集总成本和最佳路径

def optimal(mat):
    # Calculate optimal solution, a 2D list of cost and direction
    solution = []
    for _ in range(len(mat)):
        solution.append([])
        for _ in range(len(mat[0])):
            solution[-1].append((0, None))

    # Start in the bottom right corner and go backwards
    for i in range(len(mat)-1, -1, -1):
        for j in range(len(mat[0])-1, -1, -1):
            if i == len(mat) - 1 and j == len(mat[0]) - 1:
                # Bottom right corner, can not go further
                solution[i][j] = (mat[i][j], None)
            elif i == len(mat) - 1:
                # Bottom row, can only go right
                solution[i][j] = (mat[i][j] + solution[i][j+1][0], 'right')
            elif j == len(mat[0]) - 1:
                # Right column, can only go down
                solution[i][j] = (mat[i][j] + solution[i+1][j][0], 'down')
            else:
                # Any other field
                right_cost = mat[i][j] + solution[i][j+1][0]
                down_cost = mat[i][j] + solution[i+1][j][0]
                if right_cost < down_cost:
                    # Go down
                    solution[i][j] = (down_cost, 'down')
                else:
                    # Go right
                    solution[i][j] = (right_cost, 'right')

    # Walk the path and assemble the result
    i = 0
    j = 0
    path = []
    while i < len(mat) - 1 or j < len(mat[0]) - 1:
        path.append(solution[i][j][1])
        if solution[i][j][1] == 'down':
            i += 1
        else:
            j += 1

    return solution[0][0][0], path

m = [
    [1, 2, 3],
    [2, -8, 4],
    [3, 4, 6]
]

print(*optimal(m))
def最佳(mat):
#计算最佳解决方案,二维成本和方向列表
解决方案=[]
对于uu范围内(len(mat)):
解决方案。追加([]))
对于范围内的(len(mat[0]):
解决方案[-1]。追加((0,无))
#从右下角开始,然后向后走
对于范围内的i(len(mat)-1,-1,-1):
对于范围(len(mat[0])-1,-1,-1)内的j:
如果i==len(mat)-1和j==len(mat[0])-1:
#右下角,不能再往前走了
溶液[i][j]=(mat[i][j],无)
elif i==len(mat)-1:
#最后一排,只能向右走
溶液[i][j]=(mat[i][j]+溶液[i][j+1][0],“右”)
elif j==len(mat[0])-1:
#右栏,只能往下走
溶液[i][j]=(mat[i][j]+溶液[i+1][j][0],“向下”)
其他:
#任何其他领域
右成本=材料[i][j]+解决方案[i][j+1][0]
下降成本=材料[i][j]+解决方案[i+1][j][0]
如果右成本<下成本:
#下降
解决方案[i][j]=(降低成本,'down')
其他:
#向右转
解决方案[i][j]=(正确的成本,'正确的')
#沿着这条路走,把结果汇总起来
i=0
j=0
路径=[]
而i

这将打印
16[“右”、“右”、“下”、“下”]

您所说的“水平运动比垂直运动优先级更高”是什么意思?如果您有两条成本相同的路径,您会选择首先使用水平移动的路径吗?你是否最大化了水平移动的次数?你的标题问题和帖子中的问题是不同的。另外,1-6的最大成本是14吗?@AndréCascais举例来说,如果两条路径[down,right,right,down]和[down,down,right,right,down]给出相同的总成本,那么[down,right,down]就是我想要的。这不仅仅是第一步,对于矩阵1,路径1->1->2->4->6将给出最大的总成本,1+1+2+4+6=14。