天天看点

动态规划算法的理解

什么是动态规划算法?

动态规划算法其实质就是分治思想和解决冗余。因此它与分治法和贪心法类似,都是将待求解问题分解为更小的,相同的子问题,然后对子问题进行求解,最终产生一个整体最优解。

适合采用动态规划法求解的问题,经分解得到的各个子问题往往不是相互独立的。在求解过程中,将已解决的子问题的解进行保存,在需要时可以轻松地找出。

示例如下:

fibonacci数列       0   n=0

             f(n)=  1   n=1

                 f(n-1)+f(n-2)    n>1

如果n=4,则f(4)=f(3)+f(2) 则f(3)=f(2)+f(1) f(2)=f(1)+f(0).如果每个都要算,f(2),要算好几次,则效率很低下,如果n很大,则重复计算更多。所以效率很低。动态规划法,将已解决的子问题的解进行保存,在需要时可以轻松地找出,动态规划的关键在于解决冗余,将原来具有指数级复杂性的搜索算法改进成具有多项式时间的算法,这是动态规划算法的根本目的。在实现的过程中,动态规划方法需要存储各种状态,所以他的空间复杂性大于其他的算法,这是一种以空间换取时间的技术。

什么时候采用动态规划算法?

任何一种算法的思想方法都有其局限性,超出特定条件,它就失去了作用。同样动态规划算法应具备三个基本要素。

1.最优子结构性质:假设a(通常都是一个序列的组合)是全局最优解,假设a{1,e'),你只要证明

e'是除了活动1之外的最优解,这就是最优子结构

(证明:反证法,首先假设由问题的最优解导出的子问题的解不是最优的,然后在设法说明在在这个假设条件下可构造出比原问题最优解更好的解,从而导致矛盾。)

2.子问题重叠性质

递归算法求解问题时,每次产生的子问题并不总是新问题,有些子问题出现多次,这种性质称为子问题的重叠性质。子问题重叠性质并不是动态规划适用的必要条件,但是如果该性质无法满足,动态规划算法与其他算法相比就不具备优势。

3.自底向上的求解方法

由于动态规划解决的问题具有子问题重叠性质,求解时需要采用自底向上的方法,即首先选择合适的表格,将递归的停止条件填入表格的相应位置,然后将问题的规模一级一级的放大,求出每一级子问题的最优值,并将其填入表格的相应位置,直到问题所要求的规模,此时便求出原问题的最优值。

动态规划算法适合用来求解最优化问题,通常可按下列步骤对算法的求解过程进行设计。

(1)分析最优解的性质,刻画最优解的结构特征----考察是否适合采用动态规划算法。

(2)递归定义最优值(即建立递归式或动态规划方程)

(3)以自底向上的方式计算出最优值,并记录相关信息。

(4)根据计算最优值时得到的信息,构造出最优解。

在进一步探讨动态规划的设计方法及应用之前,有两点需要注意的是,一是问题的刻画对能否采用动态规划进行求解是至关重要的,不恰当的刻画方式将使问题的描述不具有最优子结构性质,从而无法建立最优值得递归关系,动态规划无从谈起。二是在算法实现过程中,应充分利用子问题的重叠性质来提高解题效率。具体地说,应采用递推(迭代)方式来编程计算有递归式定义的最优值,而不是采用直接递归的方法。

贪心算法和动态规划的区别与相同点?

这个问题是否包括重叠子问题,不是贪心算法和动态规划的区别,比如最小路径问题,它就包括重叠子问题,但是它是使用贪心算法(迪杰斯特拉算法)

相同点:都包含最优子结构性质

不同点:观察其是否真的具备贪心选择性质,如果不具备贪心选择性质,使用贪心算法,可能不一定是最优解,如果该问题具有贪心选择性质,则先考虑使用贪心选择算法。

贪心选择算法:既然是贪心的,那肯定首先对解得序列进行排序,然后从中选择出最大的,或者最小的,然后步步都是如此,其实只要证明这个贪心选择性质是能够通往最优解的,如背包问题,进行排序,然后是可以通往最优解的,如0-1背包问题,因为解释0-1问题,它可能安装贪心选择性质,装不满,则可能达不到最优解。