揹包問題-三種動態規劃解法-逐步減少空間複雜度

題目描述:有編號分別爲1,2,3,4,5的五件物品,它們的重量分別是2,2,6,5,4,它們的價值分別是6,3,5,4,6,現在給你個承重爲10的揹包,如何讓揹包裏裝入的物品具有最大的價值總和?

揹包問題是典型的動態規劃問題,也有一定的規律可循,通常採用自底向上的方式,先解決小問題,並存儲,再解決大問題。

方法一:時間空間都爲O(n^2)的解法,但可以得到最大價值情況下拿了哪些東西

這裏dp[i][j]的含義是:在只有i個物品,最大容量爲j時,能獲得的最大價值

def bag(weight, value, max_W):
    N = len(weight)
    V = max_W
    dp = [[0 for i in range(V+1)] for j in range(N+1)]

    for i in range(1,N+1):
        for j in range(1,V+1):
            if weight[i-1]<=j:
                dp[i][j] = max(dp[i-1][j],dp[i-1][j-weight[i-1]]+value[i-1])
            else:
                dp[i][j] = dp[i-1][j]
    for i in range(N+1):
        print(dp[i][:])
    return dp

def thing(weight,value,max_W,dp):	# 找出具體選了那些物品,這個可以參考第一個鏈接
    N = len(weight)
    V = max_W
    thing_flag = [0 for i in range(N)]
    j = V
    for i in range(N,0,-1):
        if dp[i][j] != dp[i-1][j]:
            thing_flag[i-1]=1
            j -= weight[i-1]
    print(thing_flag)

weight = [2,2,6,5,4]
value = [6,3,5,4,6]
max_W = 10
dp = bag(weight, value, max_W)
thing(weight,value,max_W,dp)

這個例子中對應的dp矩陣如下所示

可以通過從右下角向上回溯得到所有拿了的物品,見thing函數。

圖片參考自:https://blog.csdn.net/superzzx0920/article/details/72178544

方法二:時間爲O(n^2),空間爲O(2n)的解法

如果不需要求出具體選了哪些物品而只要最大價值,那在空間上還可以繼續優化,因爲我們求解dp[i]時,只用到了上一個子問題dp[i-1],所以存儲兩個一維數組即可。

def bag(weight, value, max_W):
    N = len(weight)
    V = max_W
    dp = [0 for i in range(V)]
    dp_next = [0 for i in range(V)]
    for i in range(N):
        for j in range(V):
            if weight[i]<=j:
                dp_next[j] = max(dp[j],dp[j-weight[i]]+value[i])
        dp = dp_next.copy()	#注意這裏要用.copy(),因爲不用就是淺複製
    print(dp_next)
    return dp

方法三:時間爲O(n^2),空間爲O(n)的解法

再進一步思考,計算dp[i][j]時只使用了dp[i-1][0……j],沒有使用dp[i-1][j+1]這樣的話,我們先計算 j 的循環時,讓j=V……1,即反方向計算,只使用一個一維數組即可。

def bag(weight, value, max_W):
    N = len(weight)
    V = max_W
    dp = [0 for i in range(V)]
    for i in range(N):
        for j in range(V-1,-1,-1):
            if weight[i]<=j:
                dp[j] = max(dp[j],dp[j-weight[i]]+value[i])
    print(dp)
    return dp
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章