【问题标题】:Find max cost path of N*N matrix, from [0,0] to [N-1,N-1] with perference in one direction找到 N*N 矩阵的最大成本路径,从 [0,0] 到 [N-1,N-1],在一个方向上具有偏好
【发布时间】:2020-04-21 21:05:30
【问题描述】:

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

| 1 | 2 | 3 |

| 2 |-8 | 4 |

| 3 | 4 | 6 |

我知道这可以通过动态编程来解决。但是,如何记录需要进行的运动?

在这种情况下,两条路径:(right, right, down, down) 的总成本与 (down, down, right, right) 完全相同,最优路径仅为 (right, right, down, down) )。

为了说清楚,我的问题是,如何找出最优路径的所有运动?

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)

【问题讨论】:

  • “水平移动优先于垂直移动”是什么意思?如果您有两条成本相同的路径,您会选择首先使用水平移动的路径吗?你是否最大化水平移动的次数?
  • 你在标题中的问题和在帖子中的问题是不同的。另外,从 1 到 6 的最大成本是 14?
  • @André Cascais 例如,如果两条路径 [down, right, right, down] 和 [down, down, right, right] 给出相同的总成本,[down, right, right, down ] 将是我想要的那个。这不仅仅是第一步。
  • @Vicrobot for matrix 1, Path 1 -> 1 -> 2 -> 4 -> 6 将给出最大总成本,1+1+2+4+6 =14。

标签: python matrix dynamic-programming


【解决方案1】:

首先以动态编程方式创建结构。先求解矩阵的底部和右侧边缘,然后重复使用这些结果求解,直到知道每个字段的最大成本和方向。

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

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))

这打印16 ['right', 'right', 'down', 'down']

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多