您的位置:首页 > 其它

背包问题(动态优化)

2014-09-29 23:33 148 查看
背包问题主要场景为:有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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: