背包问题(动态优化)

来源:互联网 发布:网络营销策划公司范文 编辑:程序博客网 时间:2024/05/09 11:39

背包问题主要场景为:有n个物品,每个物品有自身的价值与重量。有一个背包,最大承受重量为w,求背包最大能够获得的价值是多少。很显然获得最大价值有多种方案,即有多重不同的组合,使得背包中的物品价值最大。最直接的方法,是将n个物品做不同的组合,分别求出他们的价值,最后排序找出最大值。但此方法工作量大,且编程不易实现。

从极限的角度出发,若n值为最小值1时,非常好计算,只需比较物品重量与w的大小,若小于w,则物品不能放入包中,最大价值为0。若大于w,则物品能放入包中,最大价值为物品价值。若n取2时,第二个物品只能取放入与不放入两种状态。若不放入,则背包的价值为n取1时的值V1。若放入,则背包的价值为物品二的价值加上背包剩余容量所承受的最大价值,即,因此当n取2时的最大值,应为,因此n为2时的最大价值,转化为n求的值,可以采用同样的分析方法获得,此问题也转化为重量更小的同类问题。因此我们可以列出一个矩阵,横坐标为背包容量,纵坐标为物品数量,矩阵中的点为背包所能达到的最大价值。矩阵中每个点的计算公式为:

例如有5件物品[4,5,6,2,3],他们的价值为[2,4,5,7,8],背包的容量为7。则有如下矩阵:

核心代为如下所示:

public static  List<List<Integer>> getMax(ArrayList<Item> items ,int capcity){int n = items.size();List<List<Integer>> list = new ArrayList<List<Integer>>();for(int i = 0 ; i <= n ; i ++){List<Integer> values = new ArrayList<Integer>();for(int j = 0 ; j <= capcity ; j ++ ){if(i == 0 ){values.add(0);   //当物品为0个时,不管背包的容量多大,总价值都为0}else if(i == 1){     //当物品为1个时,背包的价值要不为0 ,要不为物品价值Item it = items.get(i -1);if(it.getWeight() > j){values.add(0);}else{values.add(it.getValue());}}else{Item it = items.get(i-1);if(it.getWeight() >j){ //当物品的重量大于背包容量时,物品不能放入背包中values.add(list.get(i-1).get(j));}else{int maxValue = it.getValue() + list.get(i-1).get(j - it.getWeight());values.add(maxValue > list.get(i - 1).get(j) ? maxValue : list.get(i-1).get(j));//当物品可放入背包中时,最大容量为不加该物品时的价值与加该物品价值中最大的一个}}}list.add(values);}return list;}





0 0