找到 N*N 矩阵的最大成本路径,从 [0,0] 到 [N-1,N-1],并优先考虑一个方向。

huangapple go评论90阅读模式
英文:

Find max cost path of N*N matrix, from [0,0] to [N-1,N-1] with perference in one direction

问题

例如,给定一个成本矩阵,我不仅需要知道从[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)
英文:

For example, given a cost matrix, I need to know not only the maximum sum cost to travel from [0,0] to [N-1, N-1], but also the movement I made with this optimal path. At the same time, horizonal move has higher priority than vertical move.

| 1 | 2 | 3 |

| 2 |-8 | 4 |

| 3 | 4 | 6 |

which I know could be solved through dynamic programming. However, how to record the movement needed to be made?

In this case, two path: (right, right, down, down) would give exactly same total cost as (down, down, right, right), the optimal path will only be (right, right, down, down).

To make it clear, my question is, how to find out all the movements for the optimal path?

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

得分: 1

这段代码的目标是通过动态规划来解决一个矩阵中的最优路径问题。首先,它创建了一个二维数组 solution 来存储每个位置的最优成本和移动方向。然后,它从矩阵的右下角开始,逐步计算并填充 solution 数组,找出每个位置的最优成本和移动方向。最后,它通过从左上角出发,根据 solution 数组中的信息,收集总成本和最佳路径。

这段代码打印出最佳路径的总成本和移动方向,示例矩阵 m 的输出是 16 ['right', 'right', 'down', 'down']

英文:

Start by creating a structure in dynamic programming fashion. Solve the bottom and right edges of the matrix first, then reuse these results to solve more and more until you know the max cost and direction for each field.

Then walk through the matrix from the top left corner to collect the total cost and best 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))

This prints 16 ['right', 'right', 'down', 'down']

huangapple
  • 本文由 发表于 2020年1月3日 17:43:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/59576220.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定