01背包问题

本文详细阐述了如何通过动态规划解决背包问题,以六个物品和10单位容量背包为例,展示了如何计算不同情况下背包内物品的最大价值,并确定哪些物品被选中。关键步骤包括通用逻辑和二维数组填充,最终背包价值为17,且揭示了背包中的物品组合。
摘要由CSDN通过智能技术生成

主要是填充一个二维数组,按照当前物品放入背包和不放入背包动态计算。
假设有一个容量为10的背包和6件物品(v代表价值,w代表重量):

let volumes = 10;
let goods = [
  { w: 3, v: 4 },
  { w: 2, v: 3 },
  { w: 1, v: 2 },
  { w: 5, v: 8 },
  { w: 6, v: 10 },
  { w: 8, v: 14 }
];

要把这6件商品装入背包(商品重量不能大于背包容量),达到价值最大。
首先假设只有一个商品(goods[0],{w: 3, v: 4})可以选择:
当背包容量为1的时候:装不下这个物品,此时背包中物品价值为0;
当背包容量为2的时候:装不下这个物品,价值为0;
当背包容量为3的时候:能装下这个物品,价值为4;
背包容量大于3的时候只有一个物品可以装所以也全部为4;

12345678910
0044444444

假设又增加了一个商品(goods[1],{w: 2, v: 3})可以选择:
当背包容量为1的时候:装不下这个商品,那么背包中物品的价值就与只有一个物品时的价值一样(因为当前物品装不下,所以就相当于只有第1个物品可以选),价值是0;
当背包容量是2的时候:
能装下这个商品,此时我们可以选择要不要装这个物品:
如果不装,则背包的价值就是只有第1个物品可以选择时的价值,背包容量为2时的价值:0。
如果装,则在背包容量为2且只有第1个物品可选的基础上,把背包腾出2个空间,背包价值相当于只有第1个物品可选且背包容量为0时,加上当前物品的价值:3
(这里可能有点绕,我们可以反过来思考,当背包容量为2时,有1、2两个物品可以选时,物品2确定要放入背包,那么背包的价值就是物品2的价值 + 背包容量为背包当前的容量减去物品2的重量(2-2 = 0)时且只有物品1可选时的价值
0 < 3,所以当背包容量为2的时候,把物品2放入背包,背包的价值更大。

12345678910
0044444444
03--------

当背包容量为3时:
能装下这个商品,选择要不要装这个物品:
如果不装,则背包的价值就是只有1个物品可以选择,背包容量为3时的价值:4。
如果装,则要把背包腾出2的空间,背包要腾出来容量2,背包价值相当于只有一个物品时背包容量为1时,加上当前物品的价值:3

4>3,所以当背包容量为3的时候,把物品2放入背包,背包的价值更大。

12345678910
0044444444
034-------

抽象成通用的逻辑:
当前物品是否放入包中,取决于把背包腾出当前物品的容量时的价值 + 当前物品的价值 是否大于 不放当前物品时背包的价值。

12345678910
0044444444
0344777777
2356799999
235681011131415
235681012131516
235681012141617

创建二维数组(为了方便数据处理,这里加上背包容量为0和0个物品可选的情况)

let array = [];
let rowArray = [];
for (let index = 0; index <= volumes; index++) {
  rowArray.push(0);
}
for (let index = 0; index <= goods.length; index++) {
  array.push(rowArray.slice(0, rowArray.length));
}

创建完后数据:
初始化二维数组填充二维数组:

 function fullTDArray() {
  for (let index = 1; index <= goods.length; index++) {
    let good = goods[index - 1];
    for (let weight = 1; weight <= volumes; weight++) {
      if (weight - good.w < 0 || good.v + array[index - 1][weight - good.w] <= array[index - 1][weight]) {
        array[index][weight] = array[index - 1][weight];
      } else {
        array[index][weight] = good.v + array[index - 1][weight - good.w];
      }
    }
  }
}

填充完成
所以当有上述六个物品且背包容量为10的时候,背包内物品的最大价值是17.
怎么知道背包中有哪些物品呢?
先从最后一个物品观察:
如果背包中没有最后一个物品,则相当于只有前5个物品并且背包容量为10时的价值,就是array[5][10]: 16 < 17,则说明最后一个物品肯定在背包中。
如果最后一个物品在背包中,则剩下5个物品就相当于是背包容量为(10 - 8,因为最后一个物品在背包中)2时,有5个物品可选的情况:
array[5][2] == array[4][2],说明有第5个物品跟没有第5个物品对背包价值没有影响,所以第5个物品不在背包中,依次类推,第4、3个物品也不在背包中,第2个物品在背包中。
所以背包中的物品是第6个和第2个,背包的价值是17

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值