DP为王——动态规划法学习笔记

  动态规划英文名Dynamic Programming,这个名称总让人有一种时曾相识的感觉,可能是因为容易和“线性规划”之类的概念搞混。


        首先,适用动态规划的问题十分广泛和常见——地图路径搜索(深度优先、广度优先、A*),填充容器使价值最大化(例如背包体积固定V,有不同的物体具有各自的体积和价值),文本比较算法(常用的diff工具),以及最短路径之类的求最优解的问题,幕后都有一只叫做DP的黑手操纵着。

        一个算法非常常用,说明两点:这个算法效果较好,时、空复杂度相对较好;.现实中大量问题符合这个算法的适用范围。前者并无什么特别之处,而后者正是动态规划可以称为“算法之王”的原因。

        不严谨的看,世界上的算法问题有三种:特别简单的,中等的,特别复杂的。

        特别复杂的问题,很不严谨的说就是只有穷举才能解决的问题。算法理论中被称为NP问题就是这种,没有“N的多项式时间内”的解法。这种问题往往不好被人们利用。

        特别简单的问题,解决策略往往比较明显。要么是可以简单的用贪婪法直接做,要么就是有特定的数学方法可以很快得到结果。其中能用贪婪法的问题是这样的问题:局部最优解的简单叠加即为全局最优解。举两个例子:

        1、一个小偷潜入到一个仓库里,他只能从仓库里拿三样东西,问怎样才能使小偷的利益最大化?(抢答:挑三个价值最大的货物。)

        2、你去超市购物花了N元(N为正整数),你的钱包里有1、5、10、50、100五种钞票足够多,问怎样付款能让付款的钞票张数最少?(抢答:根据价格,从100元到1元从大到小付清为止。比如128元,付100+10+10+5+1+1+1即可。)


        你一定会觉得上面两个例子既白痴又不实际,那么,我们把他们改的实际一点。

        1、一个小偷潜入到一个仓库里,他只带了一个包,包的容量为10公斤,仓库里有单件1公斤、2公斤、3公斤的货物价值分别为60元、200元、310元。问怎样带使小偷的利益最大化?

        这个问题变得非常实际了,如果小偷一着急,从3公斤的开始装,不足的空间用1公斤的补,是310+310+310+60 = 970元,还不错知足了。但是,其实装5个2公斤的,就是1000元!白赚30元。

        如果把它抽象成:包裹容量为V,货物重量weight = [w1, w2, ..., wn],货物价值value = [v1, v2, ..., vn],请你编程求解,是不是就有点困难了?自古鱼和熊掌不可兼得的问题大都符合这种模型。


        2、为纪念M国成立60周年,政府发行了大量6元和60元纪念钞票,并可以在市面上用于流通。具有“最少张钞票”强迫症的你头疼了,因为就算你备足了各种整钱和零钱,原来的付款策略也不再奏效。例如,如果付款12元,从大到小,付一张10元和两张1元就是3张;而其实你付2张6元就可以了。

        你可能会说这个问题是瞎编的。实际上,正是为了避免这种情况,所以我们的钞票才被设计成了现在这几种面值。而现实中如果不是特别设计过,那么不能用贪婪法的问题其实占大多数。

        

        现实中的问题,要解决的问题往往只有两、三个限制条件,而往往只要两、三个限制条件,就让它变得既不简单,又不是特别复杂。可喜的是,这样正好进入了动态规划的射程。


——————————————————————————————————————————————————————————————————

        跟我看几个实例:

        一片原始森林要开发为野生旅游区,一批考察人员去实地考察,规划旅游路线。森林里路线非常繁多,根据计划,从A点出发,中间必须到达中途休息区(BCD三者之一都可以,未来会选择其中一处建设成休息站)供游客休息购物,然后再出发到达E点结束。

B
起点AC终点E
D

        原始森林里,考察人员必须自己行走,然后记录自己到达每个点用的时间,用以最终确定路线。


        这个问题很简单,最终目标是A-E,它们的距离记作Lae,划分成几个子问题:

        Lab, Lac, Lad, Lbe, Lce, Lde

        Lae  = Min( Lab+Lbe, Lac+Lce, Lad+Lde )

        全局一看,无非是三条路线,选一条最短的即可。

        就说A-B这一段,也有很多走法,对考察人员来说,他们得把这些小分支都走一遍,才能找到最短的一条作为Lab。

        推广开去:

                              
                              
A147912B=12+3                      E
1




26






















5




25






















8162021222324                       

       不管路线多么复杂,总要把所有的路走一遍才能知道最短路线。因为每一个点都有可能是最终路线的一环,要所有点全部算出来才知道。
       搜索策略有很多,可以任意选择。只需要记住一个关键:当一路走来达到某一个点B时,B这一点只需要记录从起点过来最少需要x步,如果从别的途径搜索过来用了x+1步,那么这条更慢的搜索路径也没用,直接终止。如图蓝色的路线到B时,B已经记录了15,蓝色路线就不需要往上走了,可以往其他没走过的格子继续走。

        可以看出,越到后来,很多搜索途径会刚开始走就停止并不很浪费,搜索策略得当的话,这个问题的时间复杂度大致就和搜索空间一致,是O(格子数N)。实际上宽度优先搜索放在这里就是最好的方法了(反正我看起来是的)。



        再看小偷装东西的问题。

        如果背包大小是10,我们完全可以看成0、1、2、3、……、9、10  一共11个状态,每往包里放一个货物,状态就改变一次。最终达到状态10。不同的放置策略像不像一条路径?

        1、2、3公斤的三种货物价值分别是60、200、310。 每个状态的价值记作m,初始状态的价值 m0 = 0。

        状态1只能通过状态0跳过来。m1 = 60

        状态2可以通过状态1 或者 状态0 转移过来。  m2 = max( 60+60, 200 ) = 200

        状态3有三种跳转方法,从状态2来,从状态1来,从状态0来。

        状态4有三种跳转方法,从状态3来,从状态2来,从状态1来。

        状态5有三种跳转方法,从状态4来,从状态3来,从状态2来。

        依次类推……就可以得到状态10的值了,无非是从状态7、8、9跳转而来,只需要取max即可。


——————————————————————————————————————————————————————————————————

        我曾经遇到的最有情趣的一道题:一个N*N的棋盘,蚂蚁在左上角第一个格子( 0, 0 )里的位置,棋盘的每个格子里会放0~1粒蔗糖粉末。蚂蚁只能往右走或者往下走,问蚂蚁怎么走,才能使吃到的糖粉最多?


        提示:设( 0,0 )格能吃到的最大数量为m(0,0),蚂蚁每次都要从向下和向右中做出选择:

                m(x,y) = 目前这一格上的糖粉 + max( m(x+1,y), m(x,y+1) )

        这是个递推式子,可以递归来解。当然想明白以后从右下角开始往上算就可以避免递归了。


——————————————————————————————————————————————————————————————————

        大胆的抽象描述一下动态规划问题特性:

        动态规划求解的问题,不易一眼看到明确的特征。

        问题必须能够划分为若干子问题,或者叫做阶段。必须给定已知的初始阶段。

        每一个阶段都必然从之前的某一个阶段跳转而来,每一个阶段都要知道自己的最优值的判定方法,以便只保留最优的那个值。

        初始阶段经过一系列的跳转,每一步跳转都是最优解,那么达到最终阶段的时候也是最优解。(核心条件,只有满足这一条件的问题才能用动态规划法。)


反复的讨论一下:一个状态可能是最终最优跳转路径的一部分,所以大多数状态都需要被求解,虽然有可能不是。(后面会说怎么尽可能的减少求解的次数。)

有一类简单问题:只要每一步是最优解,那么结果肯定是最优解;不需要动态规划。有一类复杂问题:就算每一个子问题找到了最优解,跳转之后也不一定能得到最优解;这种问题不适用动态规划,而且不穷举的话很难求解。

符合动态规划的问题和上面二者不同:全局最优解一定是通过一系列局部最优解得来的,但是从某个局部最优解出发不一定能达到全局最优解。(举例,上面小偷装东西的问题,最终是通过2+2+2+2+2得来的,从1或者3状态出发永远也达不到最优解。)


最后,思考上最难的一点是:状态空间不仅可以是1维的,还可以是2维、3维、4维……寻找最短路径是典型的2维问题,装包是典型的1维问题。只需要修改一下小偷装东西问题,就可以变成2维的。

问题:小偷的背包容量为V,仓库里有n种货物,其价值分别为(v1,v2,...,vn),重量分别为(w1,w2,...,wn),剩余数量分别为(u1,u2,...,un),求小偷获得最大利益的方法


如果仍然使用1维的状态空间,很容易造成求得的解超过了货物的剩余数量,得到错误的解。必须使用二维空间,两个维度分别是 当前容量、当前货物总种类。最终跳转到容量为V、种类为n的节点。


——————————————————————————————————————————————————————————————

更深入的探讨,慢慢补充:

        每多一个限制条件,状态空间增加一维。有时候状态空间的意义模糊不易理解,是主要的难点所在。

        

        动态规划问题往往有两种解法:正向和反向,正向求解往往需要递归,有时候用反向可以避免递归。比如小偷装东西问题,上面说的是反向解法,没有递归。

        你还可以找到一个递推式

          m10 = max(m9+60,m8+200,m7+310)

        其中m9、m8、m7都是未知的,直接递归来做就可以了。

        而且,你发现了吗,随着递归深入,递归方式可以跳过一部分完全不需要计算的节点。举个例子,如果输入参数里,货物重量都是偶数,那么在递归的时候,奇数状态就不会被算到啦  :)  

        (我在做diff算法时感觉到能跳过的节点不多,但是反向计算肯定是全都要算出来的。)

        如果采用递归方式,务必记得用数组或者n维数组保存中间结果,不保存中间结果会反复的计算已经计算过的节点,在实际应用中觉得非常可怕。



        比较恶搞的是,最终状态不一定能达到,比如小偷装东西的问题吧,如果货物重量是4、6、8、10等等,而你的背包容量是21,那么不可能达到21,只能达到20,而且进一步的,某种组合方式可能最大值不是出现在后面的状态,所以,你得max(状态1, 状态2 ..., 状态n)才能得到真正的极值。网上无数代码存在此漏洞,包括《编程之美——微软技术面试心得》这本书。

        这又牵扯到神奇的数学,不同的数字竟然会对算法造成影响,恐怕这也是数学家的乐趣所在了 = =

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/510449.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从中间件到分布式数据库,PolarDB-X 的透明之路

PolarDB-X前身是淘宝内部使用的分库分表中间件TDDL(2007年,Java库的形态),早期以DRDS(2012年开始研发,2014年上线,分库分表中间件MySQL Proxy的形态)的品牌在阿里云上提供服务&#…

阿里云EMAS 移动测试,帮您快速掌握移动端兼容性测试技巧

一、兼容性测试可以查到哪些问题 界面适配问题,确定是否能正常安装、启动。各个页面潜在的崩溃、无响应等问题。应用性能问题,例如启动时间、页面加载时间、功耗等。 二、阿里云兼容性测试工具的功能优势 提供在线录制功能,可视化录制出功能…

零信任策略下K8s安全监控最佳实践(K+)

云原生架构新风险与需求概述 安全风险概述 传统的网络安全架构理念是基于边界的安全架构,企业构建网络安全体系时,首先要做的是寻找安全边界,把网络划分为外网、内网等不同的区域,然后在边界上部署防火墙、入侵检测、WAF等产品。…

ATC‘22顶会论文RunD:高密高并发的轻量级 Serverless 安全容器运行时

编者按:目前的安全容器软件栈 — 包括 host 操作系统中的 cgroup、guest 操作系统和用于函数工作负载的容器 rootfs,都会导致低部署密度和在低并发能力。为此,RunD 作为一种轻量级安全容器运行时,提出了 host-to-guest 的全栈优化…

getline函数

getline(istream &in, string &s) 从输入流读入一行到string s •功能:–从输入流中读入字符,存到string变量–直到出现以下情况为止:•读入了文件结束标志•读到一个新行•达到字符串的最大长度–如果getline…

Dubbo Mesh:从服务框架到统一服务控制平台

Apache Dubbo 是一款 RPC 服务开发框架,用于解决微服务架构下的服务治理与通信问题,官方提供了 Java、Golang 等多语言 SDK 实现。使用 Dubbo 开发的微服务原生具备相互之间的远程地址发现与通信能力, 利用 Dubbo 提供的丰富服务治理特性&…

struct和typedef struct彻底明白了

struct和typedef struct 分三块来讲述:   1 首先://注意在C和C里不同     在C中定义一个结构体类型要用typedef:     typedef struct Student     {     int a;     }Stu;     于是在声明变量的时候就可:Stu stu1;…

智能搜索引擎 | 驱动电商业务增长实践

开放搜索是阿里集团搜索业务中台,基于大数据深度学习在线服务体系打造的智能搜索云服务产品。拥有核心引擎、召回排序、搜索引导、充分开放等核心能力,可应用在电商行业、教育行业、内容行业等场景。目前帮助数千家客户搭建自己的搜索业务。 实践案例&a…

c++ map 函数

cMap是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据处理能力,由于这个特性,它完成有可能在我们处理一对一数据…

通过 Jenkins 构建 CI/CD 实现全链路灰度

本文介绍通过 Jenkins 构建流水线的方式实现全链路灰度功能。在发布过程中,为了整体稳定性,我们总是希望能够用小部分特定流量来验证下新发布应用是否正常。 即使新版本有问题,也能及时发现,控制影响面,保障了整体的稳…

合阔智云核心生产系统切换到服务网格 ASM 的落地实践

背景 合阔智云(http://www.hexcloud.cn) 是专注于为大中型零售连锁行业,提供全渠道业务中/前台产品和解决方案,并建立以消费者为中心的全渠道交易和敏捷供应链的新一代零售运营协同平台。 合阔智云提供了从全渠道交易管理到订单履约再到门店供应链完整…

Serverless 架构下的 AI 应用开发:入门、实战与性能优化

随着时间的推移,Serverless 架构变得越来越火热,凭借着极致弹性、按量付费、低成本运维等特性,在很多领域发挥着越来越重要的作用;机器学习领域在近些年也非常火热,并在越来越多的行业中得到应用。 实际上&#xff0c…

数据变更白屏化利器 - 推送轨迹上线

背景 Zookeeper 可作为注册配置中心,选主,分布式锁等多种场景,随着业务规模的扩大,业务之间的依赖关系逐渐变得复杂,在这种复杂的场景下如果遇到变更推送相关问题,排查起来相当困难,虽然 Zooke…

我们总结了弹性伸缩的五个条件与六个教训

前言 弹性伸缩是云计算时代给我们带来的一项核心技术红利,但是 IT 的世界中,没有一个系统功能可以不假思索的应用到所有的场景中。这篇文章,我们将应用企业级分布式应用服务-EDAS 的客户在进行系统架构设计时,在弹性场景下遇到的…

KubeVela 1.5:灵活框选 CNCF 原子能力打造独特的企业应用发布平台

KubeVela 1.5 于近日正式发布。在该版本中为社区带来了更多的开箱即用的应用交付能力,包括新增系统可观测;新增 Cloud Shell 终端,将 Vela CLI 搬到了浏览器;增强的金丝雀发布;优化多环境应用交付工作流等。进一步提升…

开源小白到核心开发——我与 sealer 的成长故事

个人简介 大家好,我是周欣元,本科就读于杭州师范大学,今年 9 月将去往云南大学进行研究生学习。本科研究方向为 docker 容器在网络攻防中的应用,目前作为 sealer member 加入了核心模块 sealer runtime 的研发工作。 个人主页&a…

全链路灰度新功能:MSE 上线配置标签推送

背景 微服务场景下,全链路灰度作为一种低成本的新功能验证方式,得到了越来越广泛的应用。除了微服务实例和流量的灰度,微服务应用中的配置项也应该具备相应的灰度能力,以应对灰度应用对特殊配置的诉求。 为什么需要配置标签推送…

hdu3527spy(STL,map)

Description The NationalIntelligence(情报工作) Council(委员会) of X Nation receives a piece ofcredible(可靠的) informationthat Nation Y will send spies(间谍) to stealNation X’s confidential(机密的) paper. So thecommander(指挥官) of TheNational Intelligen…

万节点规模云服务的 SRE 能力建设

背景及现状 系统架构简介 上图为阿里云内部实际使用的系统架构,系统主要用途为实时数据流的计算和存储。使用阿里云的容器服务 ACK 作为系统底座,容器化的部署、发布、管控等全部基于 K8s 标准。使用自己开发的 Gateway service 作为系统流量入口&#…

HDU 3532 Max Angle(计算几何——极角排序)

Description Given manypoints in a plane, two players are playing an interesting game. Player1 selects one point A as the vertex(顶点) of an angle. Then player2 selects other two points Band C. A, B and C are different with each other. Now they get an an…