簡體   English   中英

動態規划以找到二維網格的最大成本路徑

[英]Dynamic programming to find the maximum cost path of a 2D grid

給定一個二維網格,G 有 q 行和 p 列,其中每個單元格 G[i][j] 包含一個整數。 它需要從左上角 (0,0) 移動到右下角 (q-1,p-1)。 我一次只能左右移動 1 個單位。 當我訪問一個單元格時,單元格 G[i][j] 中的數量被添加到總數中。 我需要最大化總數並獲得路徑。 這是我的第一次嘗試

def findMaxPerson1(q, p, grid, memo={}):
    key = f"{q},{p}"
    if key in memo:
        return memo[key]
    if q == 0 and p == 0:  # Start point
        return grid[0][0]
    if q < 0 or p < 0:
        return 0
    up = findMaxPerson1(q-1, p, grid, memo)  # Up
    left = findMaxPerson1(q, p-1, grid, memo)  # Left
    if up >= left:
        memo[key] = up + grid[q][p]
        return memo[key]
    else:
        memo[key] = left + grid[q][p]
        return memo[key]

我從上面的代碼中得到了 15。 現在我嘗試修改以前的代碼以獲取路徑和最大總數。 這是我的嘗試代碼:

def findMaxPerson1(q, p, grid, memo={}):
        key = f"{q},{p}"
        if key in memo:
            return memo[key]
        if q == 0 and p == 0:
            return {
                'total': grid[q][p],
                'path': [(q, p)]
            }
        if q < 0 or p < 0:
            return None
        up = findMaxPerson1(q-1, p, grid, memo)  # Up
        left = findMaxPerson1(q, p-1, grid, memo)  # Left
        if up is not None and left is not None:  # Both are dictionary
            if up['total'] >= left['total']:
                up['total'] = up['total'] + grid[q][p]
                up['path'].append((q, p))
                memo[key] = up
                return up
            else:
                left['total'] = left['total'] + grid[q][p]
                left['path'].append((q, p))
                memo[key] = left
                return left
        if up is not None:
            up['total'] = up['total'] + grid[q][p]
            up['path'].append((q, p))
            memo[key] = up
            return up
        else:
            left['total'] = left['total'] + grid[q][p]
            left['path'].append((q, p))
            memo[key] = left
                return left

    print(findMaxPerson1(2, 1, grid, {}))

將此修改后的代碼與相同的網格一起使用,我得到以下輸出:

{'total': 19, 'path': [(0, 0), (1, 0), (1, 1), (2, 0), (2, 1)]}

這是我使用的網格:

grid = [
    [1, 2],
    [3, 4],
    [5, 6],
]

為什么路徑不對? 有誰知道我做錯了什么? 先感謝您。

第二種方法的問題是您正在重用和更新與memo多個鍵的值相同的對象。

第一種方法, memo的值是一個簡單的整數,當你做memo[key] = up + grid[q][p] ,值被復制。 現在up值和memo[key]值是完全獨立的。

相反,在第二種方法中,您執行以下操作:

up['total'] = up['total'] + grid[q][p]
up['path'].append((q, p))
memo[key] = up

up不復制的情況下修改up它,現在你在upmemo[key]中有相同的對象,它具有相同的更新值。


要解決這個問題簡單的方式將deepcopy的upleft修改之前,因為這樣的:

import copy
...
up = copy.deepcopy(up)
left = copy.deepcopy(left)

這解決了問題,現在第二種方法打印:

{'total': 15, 'path': [(0, 0), (1, 0), (2, 0), (2, 1)]}

但這非常低效,因為它每次都復制整個路徑,使您的算法 O(n 4 ) 而不是 O(n²)。

更好的方法是只存儲每個鍵的前一個鍵(而不是整個路徑)。 算法的主要部分完成后,您可以按照此向后引用重建路徑。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM