01背包问题从简单到复杂
生活随笔
收集整理的這篇文章主要介紹了
01背包问题从简单到复杂
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
題目:
有 N 件物品和一個(gè)容量為 V 的背包。放入第 i 件物品耗費(fèi)的費(fèi)用是 C i 1 ,得到
的價(jià)值是 W i 。求解將哪些物品裝入背包可使價(jià)值總和最大。
狀態(tài)轉(zhuǎn)移方程:
F [i, v] = max {F [i ? 1, v], F [i ? 1, v ? C i ] + W i }
基于遞歸的實(shí)現(xiàn):
這里的出口容易搞錯(cuò),出口可以從遞推方程成立條件來(lái)考慮
def pack_0_1_Rec2(N,V,C,W):if N == 0 :return 0if V < C[N-1]:return pack_0_1_Rec(N-1,V,C,W)return max(pack_0_1_Rec(N-1,V,C,W),pack_0_1_Rec(N-1,V-C[N-1],C,W) + W[N-1])基于第一種遞歸的自下而上和自上而下實(shí)現(xiàn):
# 后來(lái)仔細(xì)考慮出后之后,做了如下修正: def pack_0_1_Top_down(N,V,C,W):list = [[-1]*(V+1) for i in range(N+1)] # mins = min(C) # for i in range(N+1): # for j in range(V+1): # if i == 0 or j< mins: # list[i][j] =0list[0] = [0]*(V+1)def pack_0_1_Top_down_(N,V): # if list[N][V] == -1 and N >=1 and V >=mins:if list[N][V] == -1 and N >=1:A = pack_0_1_Top_down_(N-1,V) if V < C[N-1]: return Aelse:list[N][V] = max(A,pack_0_1_Top_down_(N-1,V-C[N-1])+W[N-1])return list[N][V]return pack_0_1_Top_down_(N,V)def pack_0_1_bottom_up(N,V,C,W):list = [[-1]*(V+1) for i in range(N+1)]list[0] = [0]*(V+1)for i in range(1,N+1):for j in range(0,V+1):A = list[i-1][j] if j < C[i-1]: list[i][j] = A else:list[i][j] = max(A,list[i-1][j-C[i-1]]+W[i-1]) # print list return list[N][V]01背包問(wèn)題的一維數(shù)組方式實(shí)現(xiàn)
凡是基于去與不去的問(wèn)題,均可使用如下方式
def pack_0_1_first(N,V,C,W):def ZeroOnePack(F,ci,wi):for v in range(V,ci-1,-1):F[v] = max(F[v],F[v-ci] + wi)return FF =[0]*(V+1)for i in range(1,N+1):ZeroOnePack(F,C[i-1],W[i-1])return F[V]01背包問(wèn)題可行性問(wèn)題
可行性問(wèn)題,想清楚初始條件
如果是,要求恰好裝滿背包,那么在初始化時(shí)除了 F [0] 為 0 ,其
它 F [1…V ] 均設(shè)為 ?∞ ,這樣就可以保證最終得到的 F [V ] 是一種恰好裝滿背包的最優(yōu)解。
如果并沒(méi)有要求必須把背包裝滿,而是只希望價(jià)格盡量大,初始化時(shí)應(yīng)該將 F [0…V ] 全部設(shè)為 0 。
運(yùn)行結(jié)果:
#%% N = 6 V = 23 C = [1,3,4,5,17,11] W = [2,9,7,5,11,4] #%% print pack_0_1_Rec(N,V,C,W) print pack_0_1_first(N,V,C,W) print pack_0_1_Top_down(N,V,C,W) print pack_0_1_bottom_up(N,V,C,W) print pack_0_1_Rec2(N,V,C,W) print pack_0_1_yes_or_no(N,V,C) 25 25 25 25 25 True總結(jié)
以上是生活随笔為你收集整理的01背包问题从简单到复杂的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 动态规划,从例子到理解
- 下一篇: 完全背包问题从简单到复杂