背包问题(动态优化)
2014-09-29 23:33
148 查看
背包问题主要场景为:有n个物品,每个物品有自身的价值与重量。有一个背包,最大承受重量为w,求背包最大能够获得的价值是多少。很显然获得最大价值有多种方案,即有多重不同的组合,使得背包中的物品价值最大。最直接的方法,是将n个物品做不同的组合,分别求出他们的价值,最后排序找出最大值。但此方法工作量大,且编程不易实现。
从极限的角度出发,若n值为最小值1时,非常好计算,只需比较物品重量与w的大小,若小于w,则物品不能放入包中,最大价值为0。若大于w,则物品能放入包中,最大价值为物品价值。若n取2时,第二个物品只能取放入与不放入两种状态。若不放入,则背包的价值为n取1时的值V1。若放入,则背包的价值为物品二的价值加上背包剩余容量所承受的最大价值,即
![](http://img.blog.csdn.net/20140929215643732)
,因此当n取2时的最大值,应为
![](http://img.blog.csdn.net/20140929215833156)
,因此n为2时的最大价值,转化为n求
![](http://img.blog.csdn.net/20140929215945796)
的值,可以采用同样的分析方法获得,此问题也转化为重量更小的同类问题。因此我们可以列出一个矩阵,横坐标为背包容量,纵坐标为物品数量,矩阵中的点为背包所能达到的最大价值。矩阵中每个点的计算公式为:
![](http://img.blog.csdn.net/20140929225509011)
。
例如有5件物品[4,5,6,2,3],他们的价值为[2,4,5,7,8],背包的容量为7。则有如下矩阵:
![](http://img.blog.csdn.net/20140929232441003)
![](http://img.blog.csdn.net/20140929232808889)
![](http://img.blog.csdn.net/20140929232833521)
![](http://img.blog.csdn.net/20140929232808889)
![](http://img.blog.csdn.net/20140929232851196)
![](http://img.blog.csdn.net/20140929233623394?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbXhsbXhsbXhsMzM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](http://img.blog.csdn.net/20140929233646997?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbXhsbXhsbXhsMzM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](http://img.blog.csdn.net/20140929233623394?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbXhsbXhsbXhsMzM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](http://img.blog.csdn.net/20140929231949062)
核心代为如下所示:
从极限的角度出发,若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; }
相关文章推荐
- 动态规划:HDU1059-Dividing(多重背包问题的二进制优化)
- 动态规划7:砝码和种类优化成01背包问题
- 算法竞赛宝典 动态规划 货币系统问题(完全背包+一维优化)
- 0-1背包问题动态规划
- 01背包问题动态规划详解(转载)
- 01背包问题动态规划详解
- 0-1背包问题的动态规划解法
- 动态规划——0/1背包问题
- 背包问题 没有进行空间优化的java代码
- 动态URL收录问题与优化
- 开始学习动态规划---先解决下背包问题
- 0/1背包问题动态规划详解
- PHP动态网页程序优化及高效提速问题
- 0/1背包问题动态规划详解
- 0/1背包问题动态规划详解(转)
- 01背包问题动态规划详解(转载)
- 动态规划解0-1背包问题
- 浅谈SEO之动态URL问题与优化
- 0/1背包问题动态规划详解之一
- 0-1背包问题的动态规划解法为什么是NPC问题?