0-1背包问题的多种解法.docx

  1. 1、本文档共20页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
一、 问题描述 0/1 背包问题 : 现有 n 种物品,对 1=i=n ,已知第 i 种物品的重量为正整数 W i,价值为正整数 Vi, 背包能承受的最大载重量为正整数 W ,现要求找出这 n 种物品的一个子集,使得子集中物 品的总重量不超过 W 且总价值尽量大。 (注意:这里对每种物品或者全取或者一点都不取, 不允许只取一部分) 二、 算法分析 根据问题描述,可以将其转化为如下的约束条件和目标函数: n wi xi W (1) i 1 xi { 0,1}( 1 i n) n max vi xi (2) i 1 于是,问题就归结为寻找一个满足约束条件( 1 ),并使目标函数式( 2 )达到最大的 解向量 X (x1, x2 , x3 ,......, xn ) 。 首先说明一下 0-1 背包问题拥有最优解。 假设 (x1, x2 , x3 ,......, xn ) 是所给的问题的一个最优解, 则 (x2 , x3 ,......, xn ) 是下面问题的 n wi xi W w1x1 max n 一个最优解: i 2 vi xi 。如果不是的话,设 ( y2 , y3 ,......, yn ) 是这 xi { 0,1}( 2 i n) i 2 n n n 个 问 题 的 一 个 最 优 解 , 则vi yi vi xi , 且 w1x1 wi yi W 。 因 此 , i 2 i 2 i 2 n n n v1x1 vi yi v1 x1vi xi vi xi ,这说明 (x1, y2 , y3 ,........, yn ) 是所给的 0-1 背包问 i 2 i 2 i 1 题比 ( x1 , x2 , x3 ,........, xn ) 更优的解,从而与假设矛盾。 穷举法: 用穷举法解决 0-1 背包问题,需要考虑给定 n 个物品集合的所有子集,找出所有可能 的子集(总重量不超过背包重量的子集) ,计算每个子集的总重量,然后在他们中找到价 值最大的子集。 由于程序过于简单,在这里就不再给出,用实例说明求解过程 。下面给出 了 4 个物品和一个容量为 10 的背包,下图就是用穷举法求解 0-1 背包问题的过程。 10 W1=7 W3=4 W4=5 V1=12 V4=25 W2=3 V3=40 V2=12 背包 物品 1 物品 2 物品 3 物品 4 ( a) 四个物品和一个容量为 10 的背包 序号 子集 总重量 总价值 序号 子集 总重量 总价值 1 空集 0 0 9 {2 ,3} 7 52 2 {1} 7 42 10 {2 ,4} 8 37 3 {2} 3 12 11 {3 ,4} 9 65 4 {3} 4 40 12 {1,2,3} 14 不可行 5 {4} 5 25 13 {1,2,4} 15 不可行 6 {1 ,2} 10 54 14 {1,3,4} 16 不可行 7 {1 ,3} 11 不可行 15 {2,3,4} 12 不可行 8 {1 ,4} 12 不可行 16 {1,2,3,4} 19 不可行 ( b )用回溯法求解 0-1 背包问题的过程 递归法: 在利用递归法解决 0-1 背包问题时,我们可以先从第 n 个物品看起。每次的递归调用 都会判断两种情况: (1 ) 背包可以放下第 n 个物品,则 x[n]=1 ,并继续递归调用物品重量为 W-w[n], 物品数目为 n-1 的递归函数, 并返回此递归函数值与 v[n] 的和作为背包问题的 最优解; (2 ) 背包放不下第 n 个物品,则 x[n]=0 ,并继续递归调用背包容量为 W ,物品数 目为 n-1 的递归函数,并返回此递归函数值最为背包问题的最优解。 递归调用的终结条件是背包的容量为 0 或物品的数量为 0.此时就得到了 0-1 背包问题 的最优解。 用递归法解 0-1 背包问题可以归结为下函数: KnapSack(n 1,m) 没有选择物品 n KnapSack(n, m) 1,m w[ n]) v[ n] 选择了物品 n KnapSack(n 第一个式子表示选择物品 n 后得到价值 KnapSack (n 1, m w[ n]) v[ n] 比不选择 物品 n 情况下得到的价值 KnapSack(n 1, m) 小,所以最终还是不选择物品 n; 第二个式 子刚好相反, 选择物品 n 后的价值 KnapSack(n 1, m w[ n]) v[n] 不小于不选择物品 n 情况下得到了价值 KnapSack( n 1, m) ,所以最终选择物品 n 。 在递归调用的过程中可以顺便求出所选择的物品。下面是标记物品被选情况的数组 x[n] 求解的具体函数表示:

文档评论(0)

156****6866 + 关注
实名认证
内容提供者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档