C#用递归算法解决经典背包问题

2019-12-30 12:55:10王旭

1.引子

  我们人类是一种贪婪的动物,如果给您一个容量一定的背包和一些大小不一的物品,裝到背包里面的物品就归您,遇到这种好事大家一定不会错过,用力塞不一定是最好的办法,用脑子才行,下面就教您如何解决这样的问题,以获得更多的奖品。

2.应用场景

  在一个物品向量中找到一个子集满足条件如下 :

  1)这个子集加起来的体积大小不能大于指定阀值

  2)这个物品子集加起来价值大小是向量V中所有满足条件1的子集中最大的

3.分析

  背包问题有好多版本,本文只研究0/1版本,即对一个物体要么选用,要么就抛弃,不能将一个物体再继续细分的情况。这种问题最简单的方法就是找出这个向量的所有子集,如同找出幂集中的子集一样,但这种遍历的方法恐怕并不会被聪明的我们所使用,现在举办这些活动的电视台也非常聪明,他们不但要求您能将物品装进去,而且指定操作时间,这样当您慢慢腾腾的装进去倒出来的时候,时间恐怕早就到了,最终您可能一无所获,这可不是我们希望的结果,我们需要使用一些策略:第一次我们可以从大小小于背包容量的物品中随意挑取一个,这样可以尽量争取时间,选取第一个后的每一个我们希望其都是最优的,这样能节省一定的时间。假设有这么一组物品,其大小和价值如下表所示:

 

物品编号 大小 价值
1 2 1
2 3 4
3 4 3
4 5 6
5 6 8

 

给我们一个容量为12的背包,让我们装上面这些物品,我们可以用下面的方法来解决寻找最优组合的问题

建立一个二围数组,数组包括n个行(n为物品数量)和capcity+1列

首先我们对第一个物品进行取舍,因为物品1大小为2,先将物品1加入背包,物品1的大小为2,则cap>=2的时候能容纳item1,这时候背包里面物品的价值为item1.Value=1,得到以下数组