动态规划初步学习及理解

栏目: 编程工具 · 发布时间: 5年前

内容简介:最近又看到一篇文章,说到算法对前端的重要性,遂抽出时间(玩的时间),逼着自己看一些相关的知识,当看到动态规划相关文献时,也勾起了很大的兴趣,学习各位大神的博客,有了初步理解,借此记载,可能比较浅显,对于同样初学相关知识的同学,或许会有帮助,如有问题,望大神指出学习的最好方法便是带着问题学习,所以首先先采用网上普遍的、对理解动态规划很友好的一个问题作为学习切入点,问题解决后再总结归纳现在有10级台阶,每次只能上1级或2级台阶,问:到达10级台阶的方法有多少?

前言

最近又看到一篇文章,说到算法对前端的重要性,遂抽出时间(玩的时间),逼着自己看一些相关的知识,当看到动态规划相关文献时,也勾起了很大的兴趣,学习各位大神的博客,有了初步理解,借此记载,可能比较浅显,对于同样初学相关知识的同学,或许会有帮助,如有问题,望大神指出

正文

学习的最好方法便是带着问题学习,所以首先先采用网上普遍的、对理解动态规划很友好的一个问题作为学习切入点,问题解决后再总结归纳

问题:

现在有10级台阶,每次只能上1级或2级台阶,问:到达10级台阶的方法有多少?

解析:

首先按照正常逻辑,看到这个问题或许会懵,因为情况太多无从下手,但是最优解往往需要更改思考方式

  1. 这里可以从结果考虑,最后我们踩在第10级台阶上,由于每次只能上1 或 2级台阶,所以上一步,我门应该在第9级台阶,或第8级台阶;
  2. 基于1的结论,从0 到 9 级台阶有多少种方法,对应的从9 到 10级台阶就有多少种方法(这里需要理解下),同理从0 到 8级台阶的方法总数等于从8 到 10级台阶的方法总数,可得从0 到 10级台阶的方法总数(以下简称methods(10))等于 从0 到 9级台阶的方法总数 加 从0 到 8级台阶的方法总数,即methods(10) = methods(9) + methods(8);这里的methods(9) 和 methods(8)就是methods(10)的 最优子结构 (思维导图有点大,只展示一部分) 动态规划初步学习及理解
  3. 从第2点我门已经发现了问题的解决逻辑和一点思路,按照第2点的思路,我们将以二叉树的形式将问题分裂成“无数”的子问题,直到分裂成 methods(2) 和 methods(1)时,methods(2)(从0 到 2级台阶的方法数)等于2,而methods(1)等于1,这里的methods(2) 和 methods(1)也就是动态规划里 边界
  4. 由3的结论,我们只需要将所有子问题的解相加便是问题结果,这里将思路转为代码,通过递归实现, methods(n) = methods(n - 1) + methods(n - 2),methods(n - 1) = ......,以此类推
function methods(n) {

    if (n == 1) return 1
    
    if (n == 2) return 2
    
    console.log('计算')
    
    return methods(n - 1) + methods(n - 2)
  }

  console.log(methods(10)); // 89

问题到这看似已经解决了,但是我想同学在思维导图中应该也发现了,很多子问题是重复的,但是上面代码却做了很多重复工作,很浪费 冗余(如下图),我们希望已经计算过的就不要在重复计算

动态规划初步学习及理解

所以优化下, 保存计算过的结果:

var resultList = [] // 保存计算过的结果,以计算的台阶数做索引下标

  function methods(n) {

    if (n == 1) return 1
    if (n == 2) return 2
    if (!resultList[n]) { // 没有就保存
      console.log('计算', n)
      resultList[n] = methods(n - 1) + methods(n - 2)
    }
    return resultList[num]
  }

动态规划初步学习及理解

这样看,就节省了很多计算,台阶总数越大,越明显

然后咱们再精简下代码:

var resultList = [0, 1, 2]; // 对于本题的结果预存了,方便点

  function fnSumF(n) {
  
    if (!resultList[n]) resultList[n] = fnSumF(n - 1) + fnSumF(n - 2);
  
    return resultList[n]
  }

总结

动态规划的英文名是Dynamic Programming,是一种分阶段求解决策问题的数学思想;与分治方法类似,都是通过组合子问题的解来来求解原问题的。再来了解一下什么是分治方法,以及这两者之间的差别,分治方法将问题划分为互不相交的子问题,递归的求解子问题,再将它们的解组合起来,求出原问题的解。而动态规划与之相反,动态规划应用与子问题重叠的情况,即不同的子问题具有公共的子子问题(子问题的求解是递归进行的,将其划分为更小的子子问题)。在这种情况下,分治方法会做许多不必要的工作,他会反复求解那些公共子子问题。而动态规划对于每一个子子问题只求解一次,将其解保存在一个表格里面,从而无需每次求解一个子子问题时都重新计算,避免了不必要的计算工作。

其实关于和分治的区别,在我们解决问题优化时已经可以看出

初学的浅层理解,如有问题希望大家指出,指点,如果问题或者好文章,也希望可以评论推荐

学的越多,才发现自己懂得越少


以上所述就是小编给大家介绍的《动态规划初步学习及理解》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

最优化理论与方法

最优化理论与方法

袁亚湘 / 科学出版社 / 1997-1 / 38.00元

《最优化理论与方法》全面、系统地介绍了无约束最优化、约束最优化和非光滑最优化的理论和计算方法,它包括了近年来国际上关于优化研究的最新成果。《最优化理论与方法》在经济计划、工程设计、生产管理、交通运输等方面得到了广泛应用。一起来看看 《最优化理论与方法》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具