1、动态规划的概念
1)动态规划是运筹学中用于求解决策过程中的最优化数学方法。 当然,我们在这里关注的是作为一种算法设计技术,作为一种使用多阶段决策过程最优的通用方法。
它是应用数学中用于解决某类最优化问题的重要工具。
2)如果问题是由交叠的子问题所构成,我们就可以用动态规划技术来解决它,一般来说,这样的子问题出现在对给定问题求解的递推关系中,这个递推关系包含了相同问题的更小子问题的解。动态规划法建议,与其对交叠子问题一次又一次的求解,不如把每个较小子问题只求解一次并把结果记录在表中(动态规划也是空间换时间的),这样就可以从表中得到原始问题的解。//记忆化搜索
关键词:
它往往是解最优化问题滴
问题可以表现为多阶段决策//多阶段决策:多阶段决策是社会经济学中动态决策问题的一个特殊形式。简言之,就是在系统的动态过程里,每一个阶段都需要进行决策。
交叠子问题:什么是交叠子问题,最优子结构性质。//最优子结构:如果问题的最优解所包含的子问题的解也是最优的,我们就称该问题具有最优子结构性质(即满足最优化原理)。最优子结构性质为动态规划算法解决问题提供了重要线索。
动态规划的思想是什么:记忆,空间换时间,不重复求解,由交叠子问题从较小问题解逐步决策,构造较大问题的解。
斐波那契数列可以作为最简单的一个例子来解释动态规划的思想,在前面讲斐波那切数列时说过了,不再叙述。
一般来说,一个经典的动态规划算法时自底向上的(从较小问题的解,由交叠性质,逐步决策处较大问题的解),它需要解出给定问题的所有较小子问题。动态规
一个变种是试图避免对不必要的子问题求解。如果采用自顶向下的递归来解,那么就避免了不必要子问题的求解(相对于动态规划表现出优势),然而递归又会导致对同一个子问题多次求解(相对于动态规划表现出劣势),所以将递归和动态规划结合起来,就可以设计一种基于记忆功能的从顶向下的动态规划算法,在后面会讲。
1
a,相同点是动态规划和分治法都划分为了较小规模问题的解
b,不同点是动态规划的较小子问题是交叠的,而且要存储较小子问题的解
2
a,参见代码,已实现
b,也可以按列来填矩阵(想想为什么?)---实际上这个问题就表明了再看动态规划第四点(填矩阵的方式表明了什么)
3
easy,在讲解中已多处指出
4
a, 空间效率也是nk,参见代码,或者从矩阵上也可看出
b,可以,这个问题的表明了再看动态规划第三点(优化空间复杂度)
---为什么可以优化,上面说过,可不可以优化,以及如何优化空间复杂度依赖于它的递推形式:
---从填矩阵的那张图可以看出,这个动态规划产生各项的过程(如果按行填的话)是上一行的第 i-1 项和第 i 项加起来产生下一行的第 i 项,传统上,我们从左往右填。
---事实上,根据它的产生过程(这个产生过程依赖于递推式自身的数学特征),可以从右往左填,这样开一个数组就行,在原数组上本地不动的填数,从右往左填可
以保证一个位置在覆盖以后不会再被用到(这是由递推式的属性决定的,需要画一画才看的比较清楚)。
这样开一个K大的数组就行了,具体的实现就不写了,已经分析的很清楚了,实现也不难
--------------------------------------------------------------------------------------------------------------------------------------------------
由以上分析,加习题,相信对于动态规划到底是什么,核心思想,具体的操作细节,以及对于动态规划的理解都加深了吧,
有2点觉得非常重要,一是填矩阵的顺序,二是动态规划空间复杂度的优化:这2点都跟递推式的依赖关系有关(这是本质),在形式上就表现为填矩阵的时候你
顺序要确保每填一个新位置时你所用到的那些位置(即它依赖的)要已经填好了,在空间优化上表现为当一个位置在以后还有用的时候你不能覆盖它。
这2条结论非常重要,是深刻理解动态规划的一个重要阶梯,我也是好久慢慢悟出来的,当然,它们有更professional的表述,在下一篇文章里我会贴出。
问题:
国际象棋中的车可以水平的或竖直的移动,一个车要从一个棋盘的一角移到对角线的另一角,有多少种最短路径?
a,用动态规划算法求解
b,用初等排列组合知识求解
b)先说b吧,这是个很简单的高中排列组合题目了,假设棋盘大小是n*n的(囧,象棋棋盘多大这个得想想才知道,就说n吧),答案是C(2n , n)
a)用a方法做下吧(主要是培养下怎么去建立动态规划的递推式)
问题是从(0,0)移动到(n,n)有多少种方法?(最短路,即横n竖n,不能回退)
设C[i , j]表示从(0,0)移动到(i ,j)的方法数(描述问题,怎么去刻画C[i , j]的含义,是动态规划的一个关键点):
那么怎么才能走到(i ,j)呢,它的上一步必定是(i-1 ,j)或者(i ,j-1)-------(分析动态规划问题的逆向思维,很重要,后面要讲)
这样就将问题描述为了交叠子问题:
C[i , j] = C[i -1, j] + C[i , j-1] ( C[i , j]的含义 )
我要求的是C[n , n]
初始条件:
C[0 , j] = j j从0到n
C[i , 0] = i i从0到n
即第一行第一列确定。
填矩阵的形式:可以按行也可以按列。
以上分析画个图很容易看出来。剩下的实现就很简单了。
我们再说下最优子结构和多阶段决策:
最优子结构:有准确的定义,可以参见一些资料,我自己描述下就是:在动态规划求解过程中的,子问题产生的解对于子问题来说也是一个最优解
多阶段决策:一步步的决策,无后效性,决策只依赖于当前状态,不依赖于之前的状态。
看看象棋问题的最优子结构性质:在到达终点之前的任意(i , j)点所走过的方法数都是最少的。
多阶段决策:每次决定往哪走只跟当前在哪有关,跟以前怎么走的无关。