簡體   English   中英

動態編程無法給出正確答案

[英]Dynamic programming doesn't give correct answer

我最近發現了一種稱為動態編程的技術,但偶然發現了一個我無法解決的問題。 開始時會給您提供一個參數列表,您需要做一些總結,就好像您要削減它一樣。 如果列表僅包含一個元素,則不對其求和。 如果還有更多,則對元素求和並以各種可能的方式進行削減。 因此,如果list具有n個元素,則只有n-1種方法可以將其剪切。 圖片將說明:

選擇

我首先想對所有可求和部分求和,我期望結果20(11 + 9)(甚至認為正確答案是9),但是我認為這將是一個不錯的開始。 但是我的代碼返回數字37,我不知道為什么。 我究竟做錯了什么?

summ = 0

def Opt( n ):
    global summ

    if len( n ) == 1:
        return 0
    else:
        summ += sum( n )
        for i in range( 1,len( n ) ):
            summ += Opt( n[ :i ] ) + Opt( n[ i: ] )

        return summ

print( Opt( [ 1,2,3 ] ) )

感謝您的時間和任何答復!

我認為這是您想要的:

def Opt(n):
    if len(n) == 1:
        return 0
    else:
        return sum(n) + min(Opt(n[:i]) + Opt(n[i:])
                            for i in range(1, len(n)))

例:

>>> Opt([1])
0
>>> Opt([1, 2])
3
>>> Opt([2, 3])
5
>>> Opt([1, 2, 3])
9
>>> Opt([1, 2, 3, 4])
19

動態編程是將“大問題”划分為小子問題。

因此,首先,您應該確定大問題與子問題之間的關系。 您可以通過編寫循環關系來實現。 在這種情況下:

Opt(nums) = sum(nums) + min(...)

您還需要一個起點:

Opt(nums) = 0 iff len(nums) == 1

如您所見,一旦編寫了遞歸關系,將其轉換為Python代碼通常很簡單。

重要的是要了解每個子問題都是獨立的,並且不需要外部輸入。 您使用global變量不僅會產生錯誤的結果,而且還違反了動態編程的精神。

您使用樹表示Opt()很好。 您忘記做的是編寫每個節點及其子節點之間的關系。 如果您這樣做了,我幾乎可以肯定您會自己找到正確的解決方案。

我們還沒有完成(感謝Stefan Pochmann注意到)。 為了構建真正的動態編程解決方案,您還需要避免多次解決同一問題。 當前,運行Opt([1,2,3,4])導致多次調用Opt([1,2]) 一種防止這種情況的方法是使用記憶:

cache = {}

def Opt(n):
    # tuple objects are hashable and can be put in the cache.
    n = tuple(n)

    if n in cache:
        return cache[n]

    if len(n) == 1:
        result = 0
    else:
        result = sum(n) + min(Opt(n[:i]) + Opt(n[i:])
                              for i in range(1, len(n)))

    cache[n] = result
    return result

順便說一句,請記住處理n為空的情況(即len(n) == 0 )。

暫無
暫無

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

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