揹包問題
㈠問題的描述
揹包問題定義如下:設u=是乙個準備放入揹包中的n個物品的集合,si和vi分別為物品ui的體積和價值(1≤i≤n),揹包的容量為c,si、vi和c均為正整數。要解決的問題是:從u中取出一些物品裝入揹包,裝入物品的體積之和不超過c,使得揹包中的物品的總價值為最大。
舉例如下:
物品集合 u=
物品體積集合 s==
物品價值集合 v==
揹包體積 c=9
正確答案是:在揹包中裝入物品u3和u4,物品總價值可達最大值13。
動態規劃法
設ui是物品集u的子集,它由u的前i項構成。從ui取出若干個物品裝入體積為j的揹包中,所形成的物品最大價值用v[i,j]表示(0≤i≤n、0≤j≤c),顯然原問題可表示為v[n,c]。
v[0,j]=0 直觀意義為:揹包中無任何物品,最大價值為0;
v[i,0]=0 直觀意義為:揹包的容量為0,最大價值為0。
當i、j>0,v[i,j]是下面二個量的最大值。
v[i-1,j]:從物品子集ui-1中取出若干物品裝入體積為j的揹包中所形成的價值最大值(即不裝入物品ui);
v[i-1,j-si]+vi:從物品子集ui-1中取出若干物品裝入容量為j-si的揹包中所形成的價值最大值。在此基礎上,再加上物品ui的價值vi,顯然j≥si (即裝入物品ui)。
物品集合 u=
物品體積集合 s==
物品價值集合 v==
揹包體積 c=9
求解v[i,j]核心之一:
if si>j then //物品ui體積si超過容量j,不裝入。
v[i,j]←v[i-1,j] //取ui-1的計算結果
else //物品ui體積si不超過容量j,可裝入。
v[i,j]←max
請注意i與j的變化規律:
i, i -1, i-2, i-3,….,i-i = 0
j-s1, j – s2, j-s3,…, 0
i與j最多有多少種組合? i*j種
最簡單的情況是什麼?
v[0,0], v[0,1]….v[0,j]
v[1,0]….v[i,0]
v[1,1],v[1,2],…v[1,j]
v[2,1],v[2,2],…,v[2,j]
揹包演算法偽**:
knapsack(page 139)
輸入:揹包容量c、物品體積集合s=、物品價值集合v=。
輸出:可裝入揹包物品的最大總價值。
(定義乙個 二維陣列v[0..n,0..c]用於計算和存放v[i,j]的值)
1. for i←0 to n v[i,0]←0 //揹包容量為0
2. for j←0 to c v[0,j]←0 //揹包未裝入任何物品
3. for i←1 to n
4. for j←1 to c
5. if si>j then //物品ui體積si超過容量j,不裝入。
6. v[i,j]←v[i-1,j] //取ui-1的計算結果
7. else //物品ui體積si不超過容量j,可裝入。
8. v[i,j]←max
9. end if
10. end for
11. end for
12. return v[n,c] //返回最大總價值
關鍵演算法方法
for i←1 to n
for j←1 to c
if si>j then //物品ui體積si超過容量j,不裝入。
v[i,j]←v[i-1,j]//取ui-1的計算結果
else //物品ui體積si不超過容量j,可裝入。
v[i,j]←max
end if
end for
end for
實現:
結果列印:
********************===揹包問題********************===
********************==第 1 次迴圈********************==
vs[0][0] = 0
vs[0][1] = 0
vs[0][2] = 0
vs[0][3] = 0
vs[0][4] = 0
vs[0][5] = 0
vs[0][6] = 0
vs[0][7] = 0
vs[0][8] = 0
vs[0][9] = 0
********************==第 2 次迴圈********************==
vs[1][0] = 0
vs[i,j] = v[i-1,j] = vs[0][1] = 0
vs[i,j] = max = max = max = max = 3
vs[i,j] = max = max = max = max = 3
vs[i,j] = max = max = max = max = 3
vs[i,j] = max = max = max = max = 3
vs[i,j] = max = max = max = max = 3
vs[i,j] = max = max = max = max = 3
vs[i,j] = max = max = max = max = 3
vs[i,j] = max = max = max = max = 3
********************==第 3 次迴圈********************==
vs[2][0] = 0
vs[i,j] = v[i-1,j] = vs[1][1] = 0
vs[i,j] = v[i-1,j] = vs[1][2] = 3
vs[i,j] = max = max = max = max = 4
vs[i,j] = max = max = max = max = 4
vs[i,j] = max = max = max = max = 7
vs[i,j] = max = max = max = max = 7
vs[i,j] = max = max = max = max = 7
vs[i,j] = max = max = max = max = 7
vs[i,j] = max = max = max = max = 7
********************==第 4 次迴圈********************==
vs[3][0] = 0
vs[i,j] = v[i-1,j] = vs[2][1] = 0
vs[i,j] = v[i-1,j] = vs[2][2] = 3
vs[i,j] = v[i-1,j] = vs[2][3] = 4
vs[i,j] = max = max = max = max = 5
vs[i,j] = max = max = max = max = 7
vs[i,j] = max = max = max = max = 8
vs[i,j] = max = max = max = max = 9
vs[i,j] = max = max = max = max = 9
vs[i,j] = max = max = max = max = 12
********************==第 5 次迴圈********************==
vs[4][0] = 0
vs[i,j] = v[i-1,j] = vs[3][1] = 0
vs[i,j] = v[i-1,j] = vs[3][2] = 3
vs[i,j] = v[i-1,j] = vs[3][3] = 4
vs[i,j] = v[i-1,j] = vs[3][4] = 5
vs[i,j] = max = max = max = max = 7
vs[i,j] = max = max = max = max = 8
vs[i,j] = max = max = max = max = 10
vs[i,j] = max = max = max = max = 11
vs[i,j] = max = max = max = max = 12
***************最後結果***************
0 0 0 0 0 0 0 0 0 0
0 0 3 3 3 3 3 3 3 3
0 0 3 4 4 7 7 7 7 7
0 0 3 4 5 7 8 9 9 12
0 0 3 4 5 7 8 10 11 12
揹包的最大價值為:12
動態規劃求解揹包問題(JAVA實現)
package com.knapsack.problem public class backpack 商品的重量 int p 商品的價值 int c backpack solution m,n,w,p 儲存運算過程的陣列 for int i 0 i n i printpack c,w,m,n par...
java動態規劃(揹包問題)
5kg的袋子 物品 物品只有乙個,且不能拆分。錢 6 10 12 kg 1 2 4 我們把5kg袋子拆分成1kg 1kg這樣的來計算,每個格仔的意思就是當前袋子在這個容量下能裝的最大價值。行表示每次加的物品 1kg2kg 3kg4kg 5kg加第乙個物品66 666加第二個物品 6 取上面第乙個 1...
01揹包問題(java,動態規劃)
一 問題描述 01揹包即每個物品最多放乙個 01 揹包問題 給定 n 種物品和乙個容量為 c 的揹包,物品 i 的重量是 wi,其價值為 vi 問 應該如何選擇裝入揹包的物品,使得裝入揹包中的物品的總價值最大?二 理論解釋 宣告乙個 大小為 m n c 的二維陣列,m i j 表示 在面對第 i 件...