java實現動態規划之背包問題


 

求解步驟:

1)建立模型

2)尋找約束條件:只有三個商品,背包重量為10

3)尋找遞推關系

V(i):價值

Wi:重量

Vi,j):當前背包容量 j,前 i 個物品最佳組合對應的價值

對於當前商品有兩種情況:

①當前商品重量大於背包剩余重量,放不進去。那么Vi-1,j=Vi,j;

②當前商品重量小於背包剩余重量,但是裝了也不一定可以達到最優解,再裝與不裝之間選一個。Max{v(i-1,j),v(i,j-w(i))+v(i)}

其中v(i-1,j):表示不裝;v(i,j-w(i))+v(i)表示裝了,背包剩余重量減少w(i),但是價值增加了v(i).由此可以得出遞推關系:

j(i)>w(i):  v(i,j)=v(i-1,j)

J(i)<w(i):  max{v(i-1,j),v(i-1,j-w(i))+v(i)}

注意:為什么可以放進去的情況下要這樣求解,因為動態規划有個最優性原理,v(i-1,j-w(i))就是前面決策造成的一種狀態,簡單來說就是現在的物品可以放進去,但是我需要做出比較,比較前面已經得出來的最優解會不會因為背包增加了新重量有了變化,從放進去和不放進去兩種情況選出最大值。后面的決策就要構成最優策略。兩種情況進行比較,得出最優。

代碼如下:

 

 1 public class BackPack1 {
 2     public void UserIput() {
 3         Scanner input=new Scanner(System.in);
 4         System.out.println("請輸入物品的個數:");
 5         int Wnumber=input.nextInt();//物品的個數
 6         System.out.println("請輸入背包的最大容量:");
 7         int MaxC=input.nextInt();//當前背包的最大容量
 8         int weight[]=new int[Wnumber];//商品重量數組
 9         int value[]=new int[Wnumber];//商品價值數組
10         for (int i = 0; i<Wnumber; i++) {
11             System.out.print("請輸入第"+(i+1)+"個商品的重量:");
12             weight[i]=input.nextInt();
13             System.out.print("請輸入第"+(i+1)+"個商品的價值:");
14             value[i]=input.nextInt();
15             System.out.println();
16         }
17         System.out.println("商品表如下:");
18         System.out.println("編號"+"\t\t"+"重量"+"\t\t"+"價值");
19         for (int i = 0; i < Wnumber; i++) {
20             System.out.print(i+1+"\t\t");
21             System.out.print(weight[i]+"\t\t");
22             System.out.println(value[i]+"\t\t");
23         }
24         int[][] V=new int[Wnumber+1][MaxC+1];
25         for (int i = 0; i < Wnumber + 1; i++)
26             V[i][0] = 0;
27         for (int j = 0; j < MaxC + 1; j++)
28             V[0][j] = 0;
29  
30         for (int i = 1; i <= Wnumber; i++) {
31             for (int j = 1; j <= MaxC; j++) {
32                 if (weight[i-1]<=j) {
33                     if (V[i-1][j]<V[i-1][j-weight[i-1]]+value[i-1]) {
34                         V[i][j]=V[i-1][j-weight[i-1]]+value[i-1];
35                     }else {
36                         V[i][j]=V[i-1][j];    
37                     }
38                 }else {
39                     V[i][j]=V[i-1][j];
40                 }
41             }
42         }
43         System.out.println("填表的結果如下:");
44         System.out.println("============================================================================");
45         for (int i = 0; i < Wnumber; i++) {
46             for (int j = 0; j <MaxC; j++) {
47                 System.out.print(V[i][j]+"\t");
48             }
49             System.out.println();
50         }
51         System.out.println("最優解是:"+V[Wnumber][MaxC]);
52     }
53 }

 

創建測試類:

public class BackPack1Text {
	public static void main(String[] args) {
		BackPack1 back=new BackPack1();
		back.UserIput();
	}

}

 運行截圖如下:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM