热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

对01背包问题的思考

经过我的一通研究,动态规划已经被我分成两大类,即分阶段决策问题以及枚举问题.在枚举界,深度优先搜索可谓明星算法,不仅如此,它还能跨界发展,因为在动态规划界,DFS天然的树状路径总

经过我的一通研究, 动态规划已经被我分成两大类,即分阶段决策问题以及枚举问题.在枚举界,深度优先搜索可谓明星算法,不仅如此,它还能跨界发展,因为在动态规划界,DFS天然的树状路径总让人觉得与DP的最优子结构有着暧昧不清的关系.如果我们能用DFS的思想去分析问题,然后最终打开一扇DP的大门就好了.
然而,事实证明上述想法里YY的成分多一些,可是DFS和DP确实存在着某种神秘关联,下面对01背包问题的分析就是铁证.

还没贴图,会补上的…

背包问题

先把问题描述清楚:

背包最大负重为5,现有三个物品,重量是(2,3,4).相应地,三个物品的价值为(10,15,20).现在要从三个物品中选择若干件装入背包.请问:在不超出背包负重上限的前提下,怎样选取才能使包中物品总价值最大?

第0个思路

经观察,应选择前两个物品.

好好好满分.现在背包容量是65536,有4096个物品可以选,麻烦再来观察一下?
别跟我提贪心,我要是再相信贪心我就是DOG.

第一个思路

不扯淡了,其实第一个想到,也是最直观的策略,一定是枚举:

方案 最终重量 最终价值
(0,0,0) 0 0
(0,0,1) 4 20
(1,1,1) 8 45

其中(0,0,0)表示”不选第一个,不选第二个,不选第三个”.

好好好,又是满分.现在背包容量是65536…

怎么枚举?

仔细分析上述枚举的过程:

  • 首先面对0号物品,我们可以选择也可以不选择;
  • 如果我们选择0号物品:
    • 现在我们面对1号物品,我们可以选择也可以不选择;
    • 如果我们选择1号物品:
      • 现在我们面对2号物品,我们可以选择也可以不选择:
      • 如果我们选择2号物品:
        • 由于已经选择了1号和2号,背包已经装满了,不能选择
      • 如果我们不选择2号物品:
        • 我们最终的选择是(1,1,0),总重量是5,总价值是25
    • 如果我们不选择1号物品:
  • 如果我们不选择0号物品

算了,直接上图吧:

更精确的表述

当处理2号物品的时候,我们需要的参数,如果背包的当前重量,已拥有的总价值等等,通通需要从树根开始计算.这肯定是不对的,正确的遍历方法是随身携带参数:

其中,节点(0,1,5)所表述的问题是

背包最大负重为5,可选物品为(0,1,2).假设我一定会选择0号物品.请问在满足题设的前提下,怎样选取剩余物品才能使背包中的价值最大?

整个问题的最终答案取决于森林中每个树的根.最终取决于森林中所有的叶.

动态规划

能用动态规划解决问题吗?回想一下,动态规划的大门前永远都站着个巨大的门神:重叠子问题,最优子结构.
最优子结构已经清楚地写到递归树的脸上去了.
然而重叠子问题在哪儿?上述递归树有相同的节点吗?

掘地三尺

找不到重叠子问题?那就往下挖.

回到递归树(森林)上.现在将注意力集中到最后一层.最后一层有两类节点,一类节点是(2,0,X),另一类是(2,1,X).各占一半.我们以(2,0,X)为例.(为了方便叙述,”第2层的节点”代表的是”森林中所有高度为2的节点”).

因为X是背包的上限,所以X非负数.又从上述分析知道,随着高度增加,X可能减少但绝不增加.再考虑到X的初始值为5.所以X最多有6个不同取值.

所以,最后一排最多有12不同的节点.

回头再看,上述分析过程中并没有用到”最后一层”这个条件,我们可以把分析应用到”第一层”或者”第二层”,这只会改变一些无关紧要的文字描述,分析过程完全不变,因此结论也完全不变.所以我们可以把结论中的”最后一层”去掉,这样结论表述为:

任意一层最多有12个不同节点.

乍一看是废话,因为森林只有3层,每层分别只有2,4,8个节点,肯定小于12.其实恰恰相反,这是个很重要的结论.

我们只要增加一个物品,比如(编号:3,重量:5,价值30),上述递归树的高度就会变成4.如果森林有第4层,它将有16个节点,由刚才的分析可以知道,这16个节点里面最多有12个不同的节点.又因为每个节点对应一个子问题,因此第4层里出现的16个子问题中,最多只有12个互不相同的子问题,即至少有4个子问题是重复的.

同理,如果森林有5层,那么第5层32个子问题里至少有20个子问题是重复的.
如果森林有6层…

重叠子问题:KAO,这都被找到了,真是R了G了.

复杂度

于是我们可以愉快地使用动态规划了.

等等,作为一个严谨的学者(别笑),我们先来分析一下复杂度吧.

现在一般化我们的问题,假设我们有N个物品,背包负重上限是M,那么背包问题复杂度的两个上限分析如下.

算法的第一个复杂度上限是O(2^N).

这个上限来自于深度优先搜索.并且这个上限并没有什么存在感,也就是说这个结论告诉我们无论算法多慢你都不比惊讶.

我们来分析算法的另一个上限.
首先每个物品在递归树上占一层.
其次,考虑到重叠子问题,以及上述一通乱七八糟的分析,我们知道每层最多有(M+1)个不同子问题.
于是我们可以轻易得出另一个上限:

O(N*M)是动态规划解决背包问题的第二个复杂度上限

这样一来,最终结论就是:

动态规划解决01背包问题的复杂度是O(2^N)和O(N*M)中较小的那个.其中N是物品个数,M是背包负重上限.

什么?你说背包上限是65536,物品有4096个?那也才不到3亿次计算而已.


推荐阅读
  • macOS Big Sur全新设计大版本更新,10+个值得关注的新功能
    本文介绍了Apple发布的新一代操作系统macOS Big Sur,该系统采用全新的界面设计,包括图标、应用界面、程序坞和菜单栏等方面的变化。新系统还增加了通知中心、桌面小组件、强化的Safari浏览器以及隐私保护等多项功能。文章指出,macOS Big Sur的设计与iPadOS越来越接近,结合了去年iPadOS对鼠标的完善等功能。 ... [详细]
  • 计算成像的原理与应用研究
    本文探讨了计算成像的原理与应用研究。首先介绍了小孔成像实验和软件方面的相关内容。随后从傅里叶光学的角度简单谈了成像的过程。成像是观测样品分布的一种方法,通过成像系统接收光的强度来呈现图像。视网膜作为接收端接收到的图像实际上是由像元组成的矩阵,每个元素代表相应位置像元接收光的强度。大脑通过对图像的分析,得出一系列信息,如识别物体、判断距离等。计算成像是一种采集记录系统,通过处理数据得到样品分布与像的对应关系,用于后续问题的分析。 ... [详细]
  • Go语言实现堆排序的详细教程
    本文主要介绍了Go语言实现堆排序的详细教程,包括大根堆的定义和完全二叉树的概念。通过图解和算法描述,详细介绍了堆排序的实现过程。堆排序是一种效率很高的排序算法,时间复杂度为O(nlgn)。阅读本文大约需要15分钟。 ... [详细]
  • 浏览器中的异常检测算法及其在深度学习中的应用
    本文介绍了在浏览器中进行异常检测的算法,包括统计学方法和机器学习方法,并探讨了异常检测在深度学习中的应用。异常检测在金融领域的信用卡欺诈、企业安全领域的非法入侵、IT运维中的设备维护时间点预测等方面具有广泛的应用。通过使用TensorFlow.js进行异常检测,可以实现对单变量和多变量异常的检测。统计学方法通过估计数据的分布概率来计算数据点的异常概率,而机器学习方法则通过训练数据来建立异常检测模型。 ... [详细]
  • 词袋模型的通俗介绍
    词,袋, ... [详细]
  • Learning to Paint with Model-based Deep Reinforcement Learning
    本文介绍了一种基于模型的深度强化学习方法,通过结合神经渲染器,教机器像人类画家一样进行绘画。该方法能够生成笔画的坐标点、半径、透明度、颜色值等,以生成类似于给定目标图像的绘画。文章还讨论了该方法面临的挑战,包括绘制纹理丰富的图像等。通过对比实验的结果,作者证明了基于模型的深度强化学习方法相对于基于模型的DDPG和模型无关的DDPG方法的优势。该研究对于深度强化学习在绘画领域的应用具有重要意义。 ... [详细]
  • 背景应用安全领域,各类攻击长久以来都危害着互联网上的应用,在web应用安全风险中,各类注入、跨站等攻击仍然占据着较前的位置。WAF(Web应用防火墙)正是为防御和阻断这类攻击而存在 ... [详细]
  • 本文介绍了互联网思维中的三个段子,涵盖了餐饮行业、淘品牌和创业企业的案例。通过这些案例,探讨了互联网思维的九大分类和十九条法则。其中包括雕爷牛腩餐厅的成功经验,三只松鼠淘品牌的包装策略以及一家创业企业的销售额增长情况。这些案例展示了互联网思维在不同领域的应用和成功之道。 ... [详细]
  • 深入解析Linux下的I/O多路转接epoll技术
    本文深入解析了Linux下的I/O多路转接epoll技术,介绍了select和poll函数的问题,以及epoll函数的设计和优点。同时讲解了epoll函数的使用方法,包括epoll_create和epoll_ctl两个系统调用。 ... [详细]
  • 面试经验分享:华为面试四轮电话面试、一轮笔试、一轮主管视频面试、一轮hr视频面试
    最近有朋友去华为面试,面试经历包括四轮电话面试、一轮笔试、一轮主管视频面试、一轮hr视频面试。80%的人都在第一轮电话面试中失败,因为缺乏基础知识。面试问题涉及 ... [详细]
  • 数据结构与算法的重要性及基本概念、存储结构和算法分析
    数据结构与算法在编程领域中的重要性不可忽视,无论从事何种岗位,都需要掌握数据结构和算法。本文介绍了数据结构与算法的基本概念、存储结构和算法分析。其中包括线性结构、树结构、图结构、栈、队列、串、查找、排序等内容。此外,还介绍了图论算法、贪婪算法、分治算法、动态规划、随机化算法和回溯算法等高级数据结构和算法。掌握这些知识对于提高编程能力、解决问题具有重要意义。 ... [详细]
  • 程序员如何选择机械键盘轴体?红轴和茶轴对比
    本文介绍了程序员如何选择机械键盘轴体,特别是红轴和茶轴的对比。同时还介绍了U盘安装Linux镜像的步骤,以及在Linux系统中安装软件的命令行操作。此外,还介绍了nodejs和npm的安装方法,以及在VSCode中安装和配置常用插件的方法。最后,还介绍了如何在GitHub上配置SSH密钥和git的基本配置。 ... [详细]
  • 谁说QLC闪存不堪大用!Intel 670p SSD深度揭秘
    ssd品牌众多,intel可以说是非常优秀的那一个,早些年的x25系列至今都是让人津津乐道的经典,不过近些年,intel固态存储的主要精力转向了企业、数据中心市场,消费级领域产品并 ... [详细]
  • 【图解HTTP】第一章 了解web及网络基础
    [图解HTTP]了解Web及网络基础Web页面是如何呈现的?根据Web浏览器地址栏中指定的URL,Web浏览器从Web服务器端获取文件资源(resour ... [详细]
  • webrtc学习笔记三:webrtc架构
    文章目录 ... [详细]
author-avatar
mobiledu2502914617
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有