经典算法详解 之 背包算法

来源:互联网 发布:阿里云服务器ping不通 编辑:程序博客网 时间:2024/06/06 18:47
    背包问题(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,放入的水果是草莓、橘子和苹果。

    到此,我们的背包问题已经解决,要了解上述算法,需要读者分析出背包算法中的每一步都做了什么操作,这一点可以通过上述的表格看出,希望本文对读者理解背包算法有所帮助!

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 帮别人办手机分期不还怎么办 国美在线没有信用卡分期不了怎么办 手机店办理分期被老板套现了怎么办 美的空调保修卡丢了怎么办 格力空调保修卡丢了怎么办 荣耀9i手机总是滑手怎么办? 春兰空调没发票不给修怎么办 洗衣机顶盖的安全开关坏了怎么办 苹果手机的开关健坏了怎么办 淘宝买的东西快递弄破损了怎么办 京东购买邮来手机里面没有怎么办 孕期建卡病历本丢了怎么办 四维检查胎儿心脏有缺陷怎么办 七个月的宝宝俩个蛋蛋都疝气怎么办 电脑有些网站看视频不能全屏怎么办 小米滑板车坏了售后不保修怎么办 红米4a电池不耐用怎么办 华为手机买个别人退货的怎么办 京东购物怎么查订单查询不到怎么办 退款了又收到货怎么办快递打电话 快递未收到货能退款商家拒绝怎么办 黑色牛仔裤有一块洗白了怎么办 黑色牛仔裤被洗衣液烧了怎么办 在蘑菇街退鞋子商家非说脏了怎么办 牛皮屑怎么办ke靠成都银康 微信订阅号取消关注之后还在怎么办 腾讯新闻红包领取说帐号异常怎么办 计算机职弥报名没选模块怎么办 有人用我手机注册有赞了怎么办 一件代发别人的货被投诉了怎么办 淘宝极速退款后商家拒收快递怎么办 运费险退到天猫垫付账户了怎么办 淘宝卖家食品有问题该怎么办 美团外卖不要辣椒给放了怎么办 旺旺卖家拒收我的消息怎么办 淘宝清空购物车大奖到上限了怎么办 游戏无响应除了退出还能怎么办 淘宝给差评了卖家一直打电话怎么办 电脑说带宽问题无法观看视频怎么办 手机淘宝上的购买信息删除了怎么办 为什么支付宝有钱淘宝付不了怎么办