算法分析与设计——动态规划求解01背包问题

这篇具有很好参考价值的文章主要介绍了算法分析与设计——动态规划求解01背包问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、算法思想

  • 假设有四个物品,如下图,背包总容量为8,求背包装入哪些物品时累计的价值最多。
    • 算法分析与设计——动态规划求解01背包问题,算法,算法,动态规划
  • 我们使用动态规划来解决这个问题,首先使用一个表格来模拟整个算法的过程。
    • 表格中的信息表示指定情况下能产生的最大价值。例如,(4, 8)表示在背包容量为8的情况下,前四个物品的最佳组合所能累计的最大价值。
      • 算法分析与设计——动态规划求解01背包问题,算法,算法,动态规划
    • 【注】第一行全0,因为第一行考虑的是前0个物品的最佳组合,也就是没有物品,它存在的意义是方便后续计算;第一列全0,因为第一列背包容量为0,不能放入任何物品,所以价值为0。
  • 现在我们需要一步一步将这个表格填好。
  • 考虑(1, 1)
    • 表示前1个物品在背包容量为1的情况下,能装入背包的最佳组合所能累计的最大价值为多少。
    • 已知,1号物品体积为2,价值为3。不能装入背包中,所以此时能产生的最大价值应该和前0个物品的一致,也就是0。
    • 算法分析与设计——动态规划求解01背包问题,算法,算法,动态规划
  • 考虑(1, 2)
    • 此时背包容量为2,前1个物品也就是1号物品刚好可以装入。那么需要考虑要不要将该物品装入背包。
    • 如果不装,那么此时的价值应该和前0个物品的一致,也就是0。
      • 算法分析与设计——动态规划求解01背包问题,算法,算法,动态规划
    • 如果装,那么此时的价值应该是该商品的价值+剩余容量所能装入的最大价值(前0个商品,2-2=0个容量),也就是3+0=3。
      • 算法分析与设计——动态规划求解01背包问题,算法,算法,动态规划
    • 然后把第二行填完,即后面都为3,因为只有第一个商品。
      • 算法分析与设计——动态规划求解01背包问题,算法,算法,动态规划
    • 2号商品体积为3,价值为4。第三行的前三列(前2个物品,容量2以内)因为不能放入2号商品,所以最大价值与前1个物品一致。
      • 算法分析与设计——动态规划求解01背包问题,算法,算法,动态规划
    • 考虑(2, 3)
      • 背包容量为3,可以放下2号物品。那么考虑要不要将该物品装入背包。
      • 如果不装,那么此时的价值应该和前1个物品的一致,为3。
        • 算法分析与设计——动态规划求解01背包问题,算法,算法,动态规划
      • 如果装,那么此时的价值应该是该商品的价值+剩余容量所能装入的最大价值(前1个商品,3-3=0个容量),也就是4+0=4。
        • 算法分析与设计——动态规划求解01背包问题,算法,算法,动态规划
    • 后面的就不再赘述,最终得到下面的表。而(4, 8)就是所能累计的最大价值
      • 算法分析与设计——动态规划求解01背包问题,算法,算法,动态规划
  • 归纳
    • 如果装不下当前物品,那么前n个物品的最佳组合和前n-1个物品的最佳组合是一样的。
    • 如果装得下当前物品(选取假设1和假设2中较大的价值,为当前最佳组合的价值)
      • 假设1:装当前物品,在给当前物品预留了相应空间的情况下,前n-1个物品的最佳组合加上当前物品的价值就是总价值。
      • 假设2:不装当前物品,那么前n个物品的最佳组合和前n-1个物品的最佳组合是一样的。
  • 虽然得到了在指定条件下,背包能装入的最大价值,但是还不知道背包中到底装了哪些物品
  • 接下来就需要进行回溯,查看每种情况下背包所装入的物品。
  • 从后往前看,(4, 8)的价值为10,考虑有没有把4号商品装入背包中。
    • 如果4号商品没有装入背包中,那么此时的价值应该和前3个商品的一致,即为9,所以4号商品是装入了背包的。
    • 算法分析与设计——动态规划求解01背包问题,算法,算法,动态规划
  • 减去4号商品的体积,剩下3个容量。接下来就只需要看前3个商品,容量为3的情况,即(3, 3)。
    • (3, 3)的体积为4,考虑有没有把3号商品装入背包中。因为此时的价值与前2个商品的一致,所以3号商品没有装入背包中。
    • 算法分析与设计——动态规划求解01背包问题,算法,算法,动态规划
  • 剩余体积不变,继续考虑前2个商品,也就是(3, 2)。
    • (3, 2)的体积为3,考虑有没有把2号商品装入背包中。因为此时的价值与前1个商品的不一致,所以2号商品是装入了背包的。
    • 算法分析与设计——动态规划求解01背包问题,算法,算法,动态规划
  • 减去2号商品的体积,剩下0个容量。没办法装入其他的商品了,到此结束。
  • 所以,当2号商品和4号商品装入背包时,能产生最大价值。
  • 归纳
    • 从表的右下角开始回溯,如果发现前n个物品最佳组合的价值和前n-1个物品最佳组合的价值一样,说明第n个物品没有被装入;否则,第n个物品被装入。

2、实例

  • 采用动态规划算法求解01背包问题,背包体积为100,商品体积和价格如下表:
    • 算法分析与设计——动态规划求解01背包问题,算法,算法,动态规划
  • python代码
    • # 求最大价值
      def max_values(goods, bag_size, goods_num):
          # 创建一个二维数组来存放最大价值,100个体积,16个商品,17行,101列(保留一列为全0)
          values = [[i for i in range(bag_size + 1)] for i in range(goods_num + 1)]
          # 计算每种情况下的最大价值
          for i in range(1, goods_num + 1):
              for j in range(1, bag_size + 1):
                  if goods[i][0] <= j:  # 商品体积小于等于背包容量
                      # 比较放入该商品和不放入该商品产生的最大价值
                      values[i][j] = max(values[i - 1][j], goods[i][1] + values[i - 1][j - goods[i][0]])
                  else:  # 商品不能放入背包,此时最大价值等于前i-1个商品的最大价值
                      values[i][j] = values[i - 1][j]
          return values
      
      
      # 回溯,求哪些商品装入了背包
      def search_goods(goods, values, bag_size, goods_num):
          good = []
          i = goods_num
          j = bag_size
          while values[i][j] != 0:
              if values[i][j] != values[i - 1][j]:  # 如果发现前n个物品最佳组合的价值和前n-1个物品最佳组合的价值不一样,说明第n个物品被装入了背包
                  good.append(i)
                  j -= goods[i][1]  # 减去该商品的体积
                  i -= 1
              else:  # 第n个物品没有被装入
                  i -= 1
          return good
      
      
      if __name__ == '__main__':
          # 共有16个商品,商品的体积和价格
          goods = [[0, 0], [5, 6], [8, 3], [28, 19], [9, 20], [6, 15], [18, 12], [21, 10], [19, 22], [19, 8], [23, 18],
                   [10, 14], [9, 13], [34, 18], [26, 19], [38, 33], [9, 10]]
          bag_size = 100  # 背包体积
          goods_num = 16  # 商品数量
          # price = [5, 8, 28, 9, 6, 18, 21, 19, 19, 23, 10, 9, 34, 26, 38, 9]
          # volume = [6, 3, 19, 20, 15, 12, 10, 22, 8, 18, 14, 13, 18, 19, 33, 10]
          values = max_values(goods, bag_size, goods_num)
          for i in range(goods_num + 1):  # 打印列表
              print(values[i])
          good = search_goods(goods, values, bag_size, goods_num)
          print("产生的最大价值为:", values[goods_num][bag_size])
          print("放入背包的商品为:", good)
  • 运行结果
    • 算法分析与设计——动态规划求解01背包问题,算法,算法,动态规划
    • 算法分析与设计——动态规划求解01背包问题,算法,算法,动态规划

文章来源地址https://www.toymoban.com/news/detail-758720.html

到了这里,关于算法分析与设计——动态规划求解01背包问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 湘潭大学 算法设计与分析实验 回溯 动态规划 贪心 模拟退火解决背包问题

    https://download.csdn.net/download/SQ_ZengYX/88620871 测试用例

    2024年02月02日
    浏览(44)
  • 【Java实现】动态规划算法解决01背包问题

    1、问题描述: 一个旅行者有一个最多能装m公斤的背包,现在有n中物品,每件的重量分别是W1、W2、……、Wn,每件物品的价值分别为C1、C2、……、Cn, 需要将物品放入背包中,要怎么样放才能保证背包中物品的总价值最大? 2、动态规划算法的概述 1)动态规划(Dynamic Progra

    2023年04月09日
    浏览(32)
  • 算法套路十四——动态规划之背包问题:01背包、完全背包及各种变形

    如果对递归、记忆化搜索及动态规划的概念与关系不太理解,可以前往阅读算法套路十三——动态规划DP入门 背包DP介绍:https://oi-wiki.org/dp/knapsack/ 0-1背包:有n个物品,第i个物品的体积为w[i],价值为v[i],每个物品至多选一个, 求体积和不超过capacity时的最大价值和,其中i从

    2024年02月10日
    浏览(37)
  • C++算法初级11——01背包问题(动态规划2)

    辰辰采药 辰辰是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师。为此,他想拜附近最有威望的医师为师。医师为了判断他的资质,给他出了一个难题。医师把他带到一个到处都是草药的山洞里对他说:“孩子,这个山洞里有一些不同的草药,采每一株都需要一些时

    2024年02月02日
    浏览(31)
  • 【算法日志】动态规划刷题:01背包问题,多重背包问题(day37,day38)

    目录 前言 目标和(01背包) 一和零(01背包) 零钱兑换(多重背包) 排列总和(多重背包) 这两天都是背包问题,其中的01背包的一些应用问题需要一定的数学建模能力,需要i将实际问题简化成我们熟悉的背包问题;而这两天的多重背包问题还算比较基础,但也要我明白了

    2024年02月11日
    浏览(33)
  • 【算法|动态规划 | 01背包问题No.2】AcWing 423. 采药

    个人主页:兜里有颗棉花糖 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 兜里有颗棉花糖 原创 收录于专栏【手撕算法系列专栏】【AcWing算法提高学习专栏】 🍔本专栏旨在提高自己算法能力的同时,记录一下自己的学习过程,希望对大家有所帮助 🍓希望我们一起努力、成

    2024年02月06日
    浏览(34)
  • 力扣算法刷题Day42|动态规划:01背包问题 分割等和子集

    力扣题目:01背包问题(二维数组) 刷题时长:参考题解 解题方法:动态规划 + 二维dp数组 复杂度分析 时间 空间 问题总结 理解递推公式困难 本题收获 动规思路:两层for循环,第一层i遍历物品,第二层j枚举背包容量以内所有值 确定dp数组及下标的含义:dp[i][j] 表示从下标

    2024年02月13日
    浏览(35)
  • 动态规划算法解决背包问题,算法分析与C语言代码实现,时间效率解析

    🎊【数据结构与算法】专题正在持续更新中,各种数据结构的创建原理与运用✨,经典算法的解析✨都在这儿,欢迎大家前往订阅本专题,获取更多详细信息哦🎏🎏🎏 🪔本系列专栏 -  数据结构与算法_勾栏听曲_0 🍻欢迎大家  🏹  点赞👍  评论📨  收藏⭐️ 📌个人主

    2023年04月16日
    浏览(39)
  • 算法竞赛必考算法——动态规划(01背包和完全背包)

    1.1题目介绍 1.2思路一介绍(二维数组) 代码如下: 1.3思路二介绍(一维数组) 空间优化   为什么可以使用一维数组?   我们先来看一看01背包问题的状态转移方程,我们可以发现 f[i]只用到了f[i-1],其他的是没有用到的,我们可以用滚动数组来做。   还有一个原因就是我

    2024年02月02日
    浏览(33)
  • 【动态规划专栏】-- 01 背包问题 -- 动态规划经典题型

    目录 背包问题概述 01 背包问题 01背包⭐⭐  【算法原理】 第一问 第二问 C++ 算法代码 复杂度分析 【空间优化 - 滚动数组】 C++ 算法代码 复杂度分析 分割等和子集⭐⭐ 【算法原理】  对于类01背包问题 C++ 算法代码  【空间优化 - 滚动数组】  C++ 算法代码 目标和⭐⭐ 【算

    2024年02月05日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包