01揹包 完全揹包 多重揹包問題分析

2021-12-29 21:24:48 字數 3633 閱讀 8973

揹包問題可以用遞迴方法和動態規劃方法,遞迴**簡潔,方便理解,不過由於重複計算,效率較低,dp方法將前面的計算結果儲存到二維陣列中,效率較高,值得推薦。

1.01揹包(zeroonepack): 有n件物品和乙個容量為m的揹包。(每種物品均只有一件)第i件物品的費用是weight[i],價值是value[i]。求解將哪些物品裝入揹包可使價值總和最大。

解題思路:對於每個物品只考慮兩種情況(放or不放),放的前提是當前物品的重量小於揹包的容量,而且放該物品時收穫的總價值大於不放該物品時的總價值,我們使用weight陣列表示物品的重量,value陣列表示物品的價值,m表示揹包的容量,n表示第n可以放或者不放,表示為遞迴函式關係可以表示如下:

if(weight[n]>m)

return recursion(weight,value,m,n-1);

else

return max(recursion(weight,value,m,n-1),recursion(weight,value,m-weight[n],n-1)+value[n]);

上述遞迴方法會有大量的遞迴重複計算,為了避免發生這種情況,我們使用dp方法,建立乙個二維陣列儲存res,則res[i][j]表示當揹包容量為i時,將前j個物品放入揹包能夠獲得的最大價值,若當前物品重量小於揹包容量,則比較放該物品時的價值res[i-weight[j]][j-1]+value[j]和不放該物品時前j-1個物品放入容量為i的揹包帶來的最大價值res[i][j-1],遞迴關係可以表示如下:if(weight[j]<=i)

else

res[i][j]=res[i][j-1];

dp程式原始碼:

#include

#include

using namespace std;

int main();

int array2[6]=;

for(int i=1;i>weight[i];

weight[i]=array1[i];

} for(int i=1;i>value[i];

value[i]=array2[i];

} vector< vector > res(m+1);

for(int i=0;i

遞迴方法程式原始碼:#include

#include

using namespace std;

int recursion(vector& weight,vector& value,int m,int n)

int main();

int array2[6]=;

for(int i=1;i>weight[i];

weight[i]=array1[i];

} for(int i=1;i>value[i];

value[i]=array2[i];

} cout<

m=10; n=5; int array1[6]=; int array2[6]=;

使用如上的一組測試資料,實驗結果如下圖所示:

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

解題思路:參考01揹包思想,只有一點稍微的改動即可,當考慮將物品j放入容量為i的揹包時,如果物品j的重量小於揹包容量i,比較放入物品j時res[i-weight[j]][j]+value[j]和不放物品j時res[i][j-1],只是第一種情況調整下基準位置的參考結果,物品可以放無數次。

dp方法程式原始碼:

#include

#include

using namespace std;

int main();

int array2[6]=;

for(int i=1;i>weight[i];

weight[i]=array1[i];

} for(int i=1;i>value[i];

value[i]=array2[i];

} vector< vector > res(m+1);

for(int i=0;i

遞迴方法原始碼:

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

解題思路:相比於前面描述的01揹包和完全揹包,這裡多重揹包增加了物品數量限制,所以在每次判斷裝入物品j時,判斷最多能放入多少個物品j,針對每乙個物品j計算最大價值,然後取最大的乙個即可。

dp方法程式原始碼:

#include

#include

using namespace std;

int main();

int array2[6]=;

int array3[6]=;

for(int i=1;i>weight[i];

weight[i]=array1[i];

} for(int i=1;i>value[i];

value[i]=array2[i];

} for(int i=1;i>size[i];

size[i]=array3[i];

} vector< vector > res(m+1);

for(int i=0;i

遞迴方法程式原始碼:

#include

#include

using namespace std;

int recursion(vector& weight,vector& value,vector& size,int m,int n)

return maxvalue;

} }int main();

int array2[6]=;

int array3[6]=;

for(int i=1;i>weight[i];

weight[i]=array1[i];

} for(int i=1;i>value[i];

value[i]=array2[i];

} for(int i=1;i>value[i];

size[i]=array3[i];

} cout<

實驗結果:

揹包問題 01揹包 完全揹包 多重揹包

01揹包和完全揹包的區別 01揹包的侷限在於每樣物品只有一種,每個物品都有乙個屬於自己的價值和重量,在給定的物品中選出揹包所能容納的最大重量,要求是價值最大 完全揹包與01揹包的不同在於完全揹包不限制每樣物品的個數,物品的價值和質量都與01揹包一樣,也同樣是求在給定大小的容量中,找出最大價值的選擇 ...

揹包問題(01揹包,完全揹包,多重揹包)

揹包問題 01揹包,完全揹包,多重揹包 近日為以下瑣事煩身 差不多要向學院提交專案申請了,本來是想做個多模式的im系統的,可是跟往屆通過審核的專案比起來,缺乏創新和研究價值,所以在文件上要多做手腳,花點心思。揹包問題,經典有揹包九講。不死族的巫妖王發工資拉,死亡騎士拿到一張n元的鈔票 記住,只有一張...

揹包問題 01揹包,完全揹包,多重揹包

有goods num件物品,max volume的最大裝載量,每種物品只有一件,每種物品都有對應的重量或者說體積volume i 價值value i 求解裝包的最大價值 假設目前已經有 i 1件物品裝在容量為 j 的揹包中,並且得到最大價值package i 1 j 當前裝第i件,那麼討論分兩個角度...