變種 揹包問題 演算法設計 揹包問題

2021-10-19 05:58:33 字數 2672 閱讀 5470

題目

乙個旅行者準備隨身攜帶乙個揹包,可以放入揹包的物品有n種,每種物品的重量和價值分別為wj, vj . 如果揹包的最大重量限制是b, 怎樣選擇放入揹包的物品以使得揹包的價值最大?

目標函式:

約束條件:

演算法設計

設fk(y) 表示只允許裝前k 種物品,揹包總重不超過y 時揹包的最大價值。fk(y)有兩種情況:不裝第k件物品或至少裝1件第k種物品。

如果不裝第k件物品,那麼只能用前k-1件物品裝入揹包,揹包的限制重量仍為y,所以最大價值是fk-1(y);

如果裝1件第k件物品,那麼裝入的第k件物品價值為vk,重量為wk,剩下的物品仍要在前k件裡選擇(因為每件物品可以裝多件,如果只能裝1件就是在前k-1件裡選擇)。於是問題規約為揹包限制重量y-wk的情況下前k件物品取得最大價值,即fk(y-wk)+vk。遞推方程與邊界條件:

上式初值比較多,f0(y)是不裝物品的最大價值;f1(y)是只能裝第一件物品時,最多裝|_y/w1_|件;遞推式fk(y-wk),y-wk有可能得到負值,即不能再裝物品,所以設定最小數以保證在優化問題中淘汰這種情況。

演算法實現

標記函式:實現是需要乙個ik(y)記錄優化函式fk(y)用到物品的最大標號。計算fk(y)時,如果fk-1(y)>fk(y-wk)+vk,即沒有加入第k件物品,ik(y)即為fk-1(y)的物品最大標號;反正,加入第k件物品,ik(y)記為k。標記函式遞迴關係:

**如下:

void knapsack(int v[n],int w[n],int f[b+1],int tagi[b+1]){

for(int k=0;k<=n;k++){

f[k][0]=0;

tagi[k][0]=0;

for(int y=0;y<=b;y++){

f[0][y]=0;

f[1][y]=(int)(y/w[0])*v[0];//只能裝第一件物品時

tagi[0][y]=0;

for(int k=1;k<=n;k++){

for(int y=1;y<=b;y++){

if(y-w[k-1]<0){

f[k][y]=f[k-1][y];

tagi[k][y]=tagi[k-1][y];

else{

//允許裝入k件物品,價值的兩種情況:

//不裝第k件物品或至少裝1件第k件物品

f[k][y]=f[k-1][y]>f[k][y-w[k-1]]+v[k-1] ? f[k-1][y]:(f[k][y-w[k-1]]+v[k-1]);

tagi[k][y]=f[k-1][y]>f[k][y-w[k-1]]+v[k-1]?tagi[k-1][y]:k;

例項及解的追蹤

試驗下面的例子:

v1=1,v2=3,v3=5,v4=9,w1=2,w2=3,w3=4,w4=7,b=10

執行結果如下圖:

我們需要在標記函式ik(y)中把實際解,及每個物品分別裝入多少件追蹤出來。

由最後i4(10)開始,i4(10)=4,表示此時第4件物品至少裝入1件,占用重量w4=7,於是揹包剩餘重量為10-7=3;繼續查詢i4(3),由i4(3)=2,表示剩餘物品最大標號為2,第2件物品至少裝入1件。剩餘重量為0,即不能再裝入物品。用公式表示追蹤解的過程:

根據例項,可以理出追蹤解的思路,**如下:

void tracksolution(int v[n],int w[n],int tagi[b+1]){

//x[i-1]標記第i件物品的件數

int x[n];

for(int i=0;i

x[i]=0;

int y=b,j=tagi[n][b];

while (tagi[j][y]!=0){

j=tagi[j][y];

//標記函式最下角ik(y)標記的物品取一件

x[j-1]=1;

y=y-w[j-1];

while (tagi[j][y]==j){

y=y-w[j];

x[j-1]=x[j-1]+1;

執行結果:

其他題目

揹包問題是很經典的動態規劃問題,很多問題都是揹包的變種,比如下面兩個題目:

設有n項任務,加工時間分別表示為正整數t1,t2,...,tn。現有2臺同樣的機器,從0時刻可以安排對這些任務的加工,知道t時刻所有任務完成,總加工時間為t。設計演算法使得總加工時間t最小的排程方案。

注意0-1揹包和揹包問題的遞推關係主要區別是:當選擇第k件物品時,fk(y)表示為fk-1(y-wk)+vk,而非fk(y-wk)+vk,即只能在前k-1件物品裡繼續選擇。另外f1(y)的邊界函式也不同。

至於第二個題目,其實就是使得一條加工線上的加工時間不超過t/2時加工時間盡可能大的問題,和第乙個問題是一樣的。

分享到:

2012-11-16 18:39

瀏覽 727

變種 揹包問題 演算法導論學習筆記(八) 揹包問題

具體的工程在我的github上。乙個正在搶劫商店的小偷發現了n個商品,第i個商品的價值vi元,重wi磅,小偷希望拿走價值盡量高的商品,但是他的揹包只能容納w磅商品,怎麼選擇才能拿走價值最大的商品?根據演算法導論書上原題和自定一些條件,把這題條件定義如下 int n new int 為了配合演算法,下...

演算法(揹包問題 01揹包問題)

01揹包問題 有 n 件物品和乙個容量是 v 的揹包。每件物品只能使用一次。第 i 件物品的體積是 vi,價值是 wi。求解將哪些物品裝入揹包,可使這些物品的總體積不超過揹包容量,且總價值最大。輸出最大價值。輸入格式 第一行兩個整數,n,v,用空格隔開,分別表示物品數量和揹包容積。接下來有 n 行,...

演算法設計 揹包問題

研究生課程系列文章參見索引 在信科的那些課 乙個旅行者準備隨身攜帶乙個揹包,可以放入揹包的物品有n種,每種物品的重量和價值分別為wj,vj 如果揹包的最大重量限制是b,怎樣選擇放入揹包的物品以使得揹包的價值最大?目標函式 約束條件 設fk y 表示只允許裝前k 種物品,揹包總重不超過y 時揹包的最大...