背包问题(Knapsackproblem)是一种组合优化的NP完全问题。问题可以描述为:给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高。这个问题涉及到了两个条件:一是物品总的大小小于或等于背包的大小,二是物品总的价值要尽量大。
如果我们用子问题定义状态来描述的话可以这样解释:
用f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值。用公式表示:
f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}或 f[v]=max{f[v],f[v-c[i]]+w[i]}
具体的解释可以理解为将前i件物品放入容量为v的背包中,现只考虑第i件物品的策略(放或不放),那么就可以转化为一个只涉及前i-1件物品和第i件物品的问题。如果不放第i件物品,那么问题就转化为“前i-1件物品放入容量为v的背包中”,价值为f[i-1][v];如果放第i件物品,那么问题就转化为“前i-1件物品放入剩下的容量为v-c[i]的背包中”,此时能获得的最大价值就是f[i-1][v-c[i]]再加上通过放入第i件物品获得的价值w[i]。(v表示背包的最大容量,c[i]表示第i件物品的大小,w[i]表示第i件物品的价值)
算法如下:
- class Fruit{
- private String name;
- private int size;
- private int price;
-
- public Fruit(String name,int size,int price){
- this.name=name;
- this.size=size;
- this.price=price;
- }
- public String getName(){
- return name;
- }
- public int getPrice(){
- return price;
- }
- public int getSize(){
- return size;
- }
- }
-
- public class Knapsack{
- public static void main(String[] args){
- final int MAX=8;
- final int MIN=1;
- int[] item=new int[MAX+1];
- int[] value=new int[MAX+1];
- Fruit fruits[]={
- new Fruit("李子",4,4500),
- new Fruit("苹果",5,5700),
- new Fruit("橘子",2,2250),
- new Fruit("草莓",1,1100),
- new Fruit("甜瓜",6,6700)
- };
- for(int i=0;i<fruits.length;i++){
- for(int s=fruits[i].getSize();s<=MAX;s++){//s表示现在背包的大小
- int p=s-fruits[i].getSize();//表示每次增加单位背包空间,背包所剩的空间
- int newvalue=value[p]+fruits[i].getPrice();//value[p]表示增加的背包空间可以增加的价值,fruits[i].getprice()表示原有的背包的价值
- if(newvalue>value[s]){//现有的价值是否大于背包为s时的价值
- value[s]=newvalue;
- item[s]=i;//将当前的水果项添加到背包的物品中
- }
- }
- }
- System.out.println("物品\t价格");
- for(int i=MAX;i>MIN;i=i-fruits[item[i]].getSize()){
- System.out.println(fruits[item[i]].getName()+
- "\t"+fruits[item[i]].getPrice());
- }
- System.out.println("合计\t"+value[MAX]);
- }
- }
程序运行的过程如下:
i=0时,放入李子
背包负重
|
1
|
2
|
3
|
4
|
5
|
6
|
7
|
8
|
s
|
-
|
-
|
-
|
4
|
5
|
6
|
7
|
8
|
p
|
-
|
-
|
-
|
0
|
1
|
2
|
3
|
4
|
value
|
0
|
0
|
0
|
4500
|
4500
|
4500
|
4500
|
9000
|
item
|
-
|
-
|
-
|
0
|
0
|
0
|
0
|
0
|
i=1时,放入蘋果
背包负重
|
1
|
2
|
3
|
4
|
5
|
6
|
7
|
8
|
s
|
-
|
-
|
-
|
-
|
5
|
6
|
7
|
8
|
p
|
-
|
-
|
-
|
-
|
0
|
1
|
2
|
3
|
value
|
0
|
0
|
0
|
4500
|
5700
|
5700
|
5700
|
9000
|
item
|
-
|
-
|
-
|
0
|
1
|
1
|
1
|
0
|
i=2时,放入橘子
背包负重
|
1
|
2
|
3
|
4
|
5
|
6
|
7
|
8
|
s
|
-
|
2
|
3
|
4
|
5
|
6
|
7
|
8
|
p
|
-
|
0
|
1
|
2
|
3
|
4
|
5
|
6
|
value
|
0
|
2250
|
2250
|
4500
|
5700
|
6750
|
7950
|
9000
|
item
|
-
|
2
|
2
|
0
|
1
|
2
|
2
|
0
|
i=3时,放入草莓
背包负重
|
1
|
2
|
3
|
4
|
5
|
6
|
7
|
8
|
s
|
1
|
2
|
3
|
4
|
5
|
6
|
7
|
8
|
p
|
0
|
1
|
2
|
3
|
4
|
5
|
6
|
7
|
value
|
1100
|
2250
|
3350
|
4500
|
5700
|
6800
|
7950
|
9050
|
item
|
3
|
2
|
3
|
0
|
1
|
3
|
2
|
3
|
i=4时,放入甜瓜
背包负重
|
1
|
2
|
3
|
4
|
5
|
6
|
7
|
8
|
s
|
-
|
-
|
-
|
-
|
-
|
6
|
7
|
8
|
p
|
-
|
-
|
-
|
-
|
-
|
0
|
1
|
2
|
value
|
1100
|
2250
|
3350
|
4500
|
5700
|
6800
|
7950
|
9050
|
item
|
3
|
2
|
3
|
0
|
1
|
3
|
2
|
3
|
由最后一个表格可以知道,在背包负重8的时候,最多得到价值9050的水果,这个时候可以得到装入的水果是3号水果草莓,那么剩下的(8-1=7)个大小空间,可以知到为2号水果也就是橘子,同理下一步可以知道放入的水果是1号水果苹果。此时获得的最优解的价值就是9050,放入的水果是草莓、橘子和苹果。
更多信息请查看 java进阶网 http://www.javady.com
分享到:
相关推荐
原先在网上找到某位大虾写的一个简单的背包算法,于是在其基础上改成适合我们目前项目中要求的背包算法。此算法要求传入一组对象集合(其中的对象中只包含主键和值)和某个条件值,然后能打印sum(对象.值)条件的1个...
最优装载问题,也被称为集装箱装载或货车装载问题,是一个经典的组合优化问题,广泛存在于物流、运输和资源分配等领域。在计算机科学中,它通常被处理为一个求解最大化的二进制背包问题,目的是在有限的容量下,尽...
三、价值背包算法 在本项目中,我们特别关注价值背包问题,即每个物品的价值和重量不等。在选择物品时,不仅考虑其重量,还要考虑其对整体价值的贡献。通过遗传算法,我们能够平衡重量限制与价值最大化的关系,找到...
本项目中,遗传算法被应用于解决经典的背包问题,这是一种典型的组合优化问题。在背包问题中,我们通常有一组物品,每件物品都有一个重量和价值,目标是在不超过背包总容量的前提下,选取物品以最大化总价值。 首先...
贪心算法的优点是思路简单,易于实现,但并不总是能得到全局最优解,因为它的每一步选择都是局部最优的,而全局最优可能需要考虑更多的组合可能性。在背包问题中,贪心算法对于某些特定类型的问题(如完全背包、非...
背包算法是计算机科学中的一种经典算法,用于解决组合优化问题。该算法的提出可以追溯到1978年,Merkel和Hellman提出了该问题。该算法的主要思想是,在给定总重量的限制下,如何选择物品,使得总价值最高。 在...
背包问题是一类典型的组合优化问题,通常涉及在给定的容量限制下,从一系列物品中选择最优组合,以使总价值最大化或总重量最小化。背包问题有多种变体,如0-1背包问题(每个物品只能取或不取)、完全背包问题(每个...
背包问题是一类经典的组合优化问题,其基本形式为:给定一系列物品,每种物品都有一定的价值(或利润)和重量,要求从中选择若干物品放入背包中,使得总重量不超过背包容量的情况下,背包内物品的总价值最大。...
背包问题是计算机科学领域内一个经典的组合优化问题,通常被用来作为算法设计与分析的案例之一。该问题可以表述为:给定一系列物品,每件物品有一个重量和一个价值;另有一个背包,其容量有限。目标是在不超过背包...
PSO算法可以应用于此类问题,通过模拟粒子群的群体智能来寻找最优或近似最优的物品组合方案。 在进行PSO算法处理0-1背包问题的过程中,我们需要定义几个关键元素:首先是粒子的表示方法,即如何将粒子的位置与物品...
### 背包算法经典:深入解析背包九讲 #### 第一讲:01背包问题 **知识点概览**:01背包问题是最基础的背包问题类型,涉及到的每种物品仅有一件,且每件物品只能选择放入背包或不放入背包。此问题通过动态规划方法...
总结来说,本案例通过粒子群算法解决了背包问题,利用群体智能寻找最优的物品选择方案,体现了PSO在处理复杂优化问题上的潜力。通过深入理解并实践这种算法,我们可以解决许多实际工程和科学领域的优化挑战。
贪心算法并不总是能找到全局最优解,但在某些特定情况下,如背包问题,它能提供一个接近最优的解决方案。贪心算法的步骤通常是:对问题进行分解,然后在每一步选择局部最优解,希望这些局部最优解组合起来能得到全局...
### 背包算法+近似算法+近似方案 #### 一、引言与背景 背包问题(Knapsack Problem)是计算机科学与运筹学中的一个经典问题,广泛应用于资源分配、优化决策等领域。它主要研究的是如何在有限的资源约束下,通过...
0-1背包问题是一种经典的组合优化问题,在实际应用中有着广泛的应用场景,比如物流分配、资源调度等领域。该问题的核心是:给定一系列物品(每个物品有其价值和重量),以及一个背包的最大承重能力,要求在不超过...
贪心算法通常不是解决0-1背包问题的最优方法,因为它无法保证全局最优解。贪心策略可能会选取局部最优的物品,但忽视了整体的最优解。例如,贪心算法可能会优先选择价值/重量比高的物品,但这可能导致背包空间的浪费...
在背包问题中,贪心算法通常用于解决“最佳装载”背包问题,即在不超过背包最大重量限制的情况下,选择价值最大的物品组合。 **最佳装载背包问题** 在这个问题中,我们可以将物品按照单位重量的价值(价值除以重量...
6. **解码**:最后,将最优的个体解码为实际的物品选择方案,即背包问题的最优解。 MATLAB作为一个强大的数值计算环境,提供了丰富的工具箱支持优化算法的实现,包括遗传算法和量子计算的相关库。开发者可以根据...
0/1背包算法与决策树ID3算法实现 本文主要讨论了 0/1 背包动态规划算法与决策树 ID3 算法的实现 DETAILS 。 0/1 背包问题 0/1 背包问题是一种组合优化的 NP 完全问题。问题可以描述为:给定一组物品,每种物品都...