混合背包问题,和多重背包问题一样的处理
生活随笔
收集整理的這篇文章主要介紹了
混合背包问题,和多重背包问题一样的处理
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
問題
如果將三種背包問題混合起來。也就是說,有的物品只可以取一次(01背包),有的物品可以取無限次(完全背包),有的物品可以取的次數有一個上限(多重背包)。應該怎么求解呢?
轉化為01背包問題,對的就是和多重背包一模一樣,min(V // C[i],M[i])包含了3中情況:
def change_multiple_to_01(N,V,C,W,M):C_ =[]W_ =[]for i in range(N):t = min(V // C[i],M[i])k = 1j = twhile 2*k <= t:C_.append(k*C[i])W_.append(k*W[i]) j -= kk *= 2C_.append(j*C[i])W_.append(j*W[i])def pack_0_1_first(N,V,C,W): F =[0]*(V+1) for i in range(1,N+1):for v in range(V,C[i-1]-1,-1):F[v] = max(F[v],F[v-C[i-1]] + W[i-1])return F[V]N_ = len(C_)return pack_0_1_first(N_,V,C_,W_)使用通用的狀態方程:F [i , v] = max {F [i ? 1, v ? k ? C i ] + k ? W i | 0 ≤ k ≤ min{M i,V//Ci}
def pack_01_and_complete_and_multiple_Bottom_up(N,V,C,W,M):list = np.zeros((N+1,V+1),dtype=int)for i in range(1,N+1):for j in range(0,V+1):t = min(j // C[i-1],M[i-1])result = -1000for k in range(t+1):A = list[i-1,j-k*C[i-1]] + k*W[i-1]if A > result:result = Alist[i,j] = result return list[N,V]假如01和完全混合,可以簡化如下處理:
def pack_01_and_complete_Bottom_up(N,V,C,W,M):list =[0]*(V+1)for i in range(1,N+1):if M[i-1] == 1:for v in range(V,C[i-1]-1,-1):list[v] = max(list[v],list[v-C[i-1]] + W[i-1])if M[i-1] == 1000:for v in range(C[i-1],V+1):list[v] = max(list[v],list[v-C[i-1]] + W[i-1]) return list[V]運行結果:
#%% N = 7 V = 100 C = [11,2,3,9,13,6,7,5] W = [1,2,9,7,5,11,6,14] M = [1000,1,1000,1,1000,1,1,1]print pack_multiple_Bottom_up(N,V,C,W,M) print change_multiple_to_01(N,V,C,W,M) print pack_01_and_complete_Bottom_up(N,V,C,W,M) print pack_01_and_complete_and_multiple_Bottom_up(N,V,C,W,M)print change_multiple_to_01_yes_or_no(N,V,C,M) print pack_multiple_yes_or_no(N,V,C,M)297 297 297 297 True 1總結
以上是生活随笔為你收集整理的混合背包问题,和多重背包问题一样的处理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 完全背包问题从简单到复杂
- 下一篇: 背包问题追踪解