因为前一段接了个项目,所以呢,其实在前一段时间我就有写过关于动态规划的一篇文章——浅谈一下这个所谓的特殊算法——动态规划!链接如下:
但是在项目的讲述中,如果我要使用到它,我怎么讲述?忽的这样一想,好像对其算法好像并没有自己想的那个随意。所以再来说到说到这个动态规划!
我们在一些搜索引擎上搜索——基于动态规划时,你会发现关于使用动态规划的领域,可谓是各行各业。比如:基于动态规划的资源分配问题,基于动态规划的路径规划方法等等等。其实早在最初的浅谈动态规划中,我就提出过DP实际意义上说是一个方法,并非一个算法!!
下面我先主要针对于动态编程进行一定的解释说明:
维基百科的意思大致是:动态编程既是数学优化方法又是计算机编程方法。该方法是由理查德·贝尔曼(Richard Bellman)在1950年代开发的,并且已在从航空工程到经济学的许多领域中得到应用。在这两种情况下,它都是指通过以递归方式将其分解为更简单的子问题来简化一个复杂的问题。尽管无法以这种方式解决某些决策问题,但是跨越多个时间点的决策通常会递归拆分。同样,在计算机科学中,如果可以通过将问题分解为子问题然后递归地找到子问题的最优解来最佳地解决问题,则可以说它具有最优子结构。
动态编程的介绍
动态编程是解决优化问题的最强大的设计技术。
分而治之算法将问题划分为不相交的子问题,然后递归地解决子问题,然后结合其解决方案来解决原始问题。
当子问题不是独立的时,例如当它们共享相同的子问题时,使用动态编程。在这种情况下,分治法可能会做比必要的更多的工作,因为它可以多次解决同一个子问题。
动态编程仅解决每个子问题一次,并将结果存储在表中,以便在需要时可以重复检索它。
动态编程是一种**自下而上的方法-**我们解决所有可能的小问题,然后结合以获得更大问题的解决方案。
动态规划是一种算法设计的范式,其中,通过实现子问题解决方案以及出现“ 最优原理 ” 的组合来解决优化问题。
动态编程的特点
当问题具有以下特征时,动态编程将起作用:
- **最优子结构:**如果最优解决方案包含最优子解决方案,那么问题将表现出最优子结构。
- **子问题重叠:**当递归算法将重复访问相同的子问题时,则问题将具有子问题重叠。
如果问题具有最佳子结构,则可以递归定义最佳解决方案。如果问题有重叠的子问题,那么我们可以通过仅计算每个子问题一次来改进递归实现。
如果问题没有最佳子结构,则没有基础来定义递归算法以找到最佳解决方案。如果一个问题没有重叠的子问题,那么使用动态编程就无济于事。
如果子问题的空间足够大(即输入大小为多项式),则动态编程比递归更有效。
动态编程的要素
基本上,三个要素是动态编程算法的特征:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SWAX3nC3-1584971186276)(https://static.javatpoint.com/tutorial/daa/images/elements-of-dynamic-programming.png)]
- **子结构:**将给定问题分解为较小的子问题。用较小问题的解决方案来表达原始问题的解决方案。
- **表结构:**解决了子问题后,将结果存储到表中的子问题中。这样做是因为子问题解决方案已被多次重用,并且我们不想一遍又一遍地重复解决相同的问题。
- **自下而上的计算:**使用表格,将较小的子问