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();
	}

}

 运行截图如下:

 

posted @ 2019-07-18 23:26  修仙小华  阅读(1867)  评论(0编辑  收藏  举报