《JAVA》中利用《動態規劃》實現《揹包》問題

2021-07-09 02:17:05 字數 4730 閱讀 2538

揹包問題

㈠問題的描述

揹包問題定義如下:設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 件...