完全揹包問題

2021-08-31 08:28:43 字數 1217 閱讀 4011

完全揹包問題的描述:

有n 種物品和乙個容量為v 的揹包,每種物品都有無限件可用。第i 種物品的費用是c[i],價值是w[i]。求解將哪些物品裝入揹包可使這些物品的費用總和不超過揹包容量,且價值總和最大。

可能大家已經看出來了,完全揹包問題其實就是在0/1揹包的問題的基礎上加了乙個條件:每種物品都有無限件可用。

這個問題有不少解法,下面只給出最優化的o(vn)的演算法。

這個演算法使用一維陣列,先看偽**:

for i=1..n

for v=0..v

f[v]=max

你會發現,這個偽**與01揹包的偽**只有v 的迴圈次序不同而已。為什麼這樣一改就可行呢?首先想想為什麼01揹包中要按照v=v..0的逆序來迴圈。這是因為要保證第i次迴圈中的狀態f[i][v]是由狀態f[i-1][v-c[i]]遞推而來。換句話說,這正是為了保證每件物品只選一次,保證在考慮「選入第i 件物品」這件策略時,依據的是乙個絕無已經選入第i 件物品的子結果

f[i-1][v-c[i]]。而現在完全揹包的特點恰是每種物品可選無限件,所以在考慮「加選一件第i種物品」這種策略時,卻正需要乙個可能已選入第i種物品的子結果f[i][v-c[i]],所以就可以並且必須採用v=0..v的順序迴圈。這就是這個簡單的程式為何成立的道理。值得一提的是,上面的偽**中兩層for迴圈的次序可以顛倒。這個結論有可能會帶來演算法時間常數上的優化。

這個演算法也可以以另外的思路得出。

例如,將基本思路中求解f[i][v-c[i]]的狀態轉移方程顯式地寫出來:

f[i][v]=max

你會發現,我們用二維陣列 的解法做的時候,都是扣掉 當前的容量所剩下的容量最多能放多少,取的是上一行的資料: f[i-1][v],這是因為在當前揹包加入的之前,上一行就表示出了 加入上乙個揹包時的最優解。而其實每一行都比上一行優化,因為每往下走一行,就加入了乙個揹包,比原來的選擇多,得出的優化值自然比上一行的優化。

知道了每一行都比上一行優化之後 ,完全揹包問題的答案就可以得出來了,我們每次都取當前行,即f[i][v],那麼原狀態方程就變成了:f[i][v]=max,呵呵,二維陣列的第一維都變成i了,就是說都在同一行進行比較了。這樣的話就可以把它轉化成一維陣列問題了。即,直接把[i]去掉。。。

最後抽象出處理一件完全揹包類物品的過程偽**:

procedure completepack(cost,weight)

for v=cost..v

f[v]=max

上傳了乙個參考文件,有興趣的同志可以自己去看看

揹包問題(完全揹包)

1.矩陣鏈乘法 2.投資組合問題 3.完全揹包問題 4.01揹包問題 5.最長公共子串行 乙個揹包,可以放入n種物品,物品j的重量和價值分別為,如果揹包的最大重量限制是b,怎麼樣選擇放入揹包的物品以使得揹包的總價值最大?組合優化問題,設表示裝入揹包的第j個物品的數量,解可以表示為。那麼目標函式和約束...

完全揹包問題

這個是從ppt上弄過來的。完全揹包問題 有n種物品和乙個容量為v的揹包,每種物品都有無限件可用。放入第i種物品的耗費的空間是ci,得到的價值是wi。求解 將哪些物品裝入揹包,可使這些物品的耗費的空間總和不超過揹包容量,且價值總和最大 基本思路 這個問題非常類似於01揹包問題,所不同的是每種物品有無限...

完全揹包問題

設有n種物品,每種物品有乙個重量及乙個價值。但每種物品的數量是無限的,同時有乙個揹包,最大載重量為m,今從n種物品中選取若干件 用乙個物品可以多次選取 使其重量的和小於等於m,而價值的和為最大。輸入有多組資料,對於每組輸入資料第1行 兩個整數,m 揹包容量,m 200 和n 物品數量,n 30 第2...