您的位置:首页 > 其它

浅谈动态规划

2015-10-16 17:54 155 查看

浅谈动态规划

     在各类计算机书籍上,我们都不难找到关于动态规划的严密定义。维基百科关于动态规划的定义:In mathematics, computer science, economics, and bioinformatics, dynamic programming is a method for solving a complex problem by breaking it down into a collection of simpler subproblems. 现在让我们抛去严谨的定义,将它只认为是解决某一类问题的关键方式。

运用动态规划往往会获得远远高于朴素解法的运行效率,有人可能会问,动态规划究竟有什么过人之处?别慌,让我们来望文生义,动态规划便是动态地解决问题。这里我们又要引出一个新的概念,子问题,通过求解子问题再进行递推来获得最终的答案便是动态规划核心所在,要完成这个则需要我们获得状态与状态之间的关系以及状态转移方程。你说什么是状态转移方程?其实也就是一个递推关系式,我们可以通过一个简单的例子进行说明。比如我们要求5*n的值(现在假定我们没有学过任何乘法口诀!),举个例子当n=5时,ch(5)=5+5+5+5+5,ch(n)=5+5+5+……+5(n个5);再来动态规划解决(dp):

dp(0)=0;dp(1)=0+5;dp(2)=0+5+5;dp(3)=0+5+5+5;dp(4)=0+5+5+5+5;不难看出dp(n)=dp(n-1)+5,可能乍一看dp(n)和ch(n)没有什么区别,但是当n很大时(例如10000000000),我们已知dp(n-1)的值,此时只需一步便可求出dp(n)的值,而如果用朴素算法,则需要进行10000000000次运算,动态规划的过人之处由此体现。下面我们通过解决一个具体的问题来进一步了解动态规划。

     问题描述:给出一个长度为n的整数序列,a[1],a[2],a[3],a[4],……,a
,(a[]可以理解为是一个容器,1,2,3……,n为容器中相应的单元格,存放着各自的信息,取用时各自不受到干扰)求出它的一个递增的子序列(不一定连续),并使得子序列中的元素个数尽可能的多。假设{1,6,3,5,4,2,7},那么此序列的最长递增子序列(以下简称LIS)为{1,3,4,7}或{1,3,5,7},长度为4。

     LIS问题的最优子结构特性决定了它为动态规划的经典应用,与上边的例子一样,当n小的时候我们甚至可以利用肉眼求得LIS,但当n很大时,我们该怎么办?

别虚!上面那个例子我们可以利用dp(n-1)通过一步计算求得dp(n),那么此处的动态规划是否也是如此呢?我们用m[i]表示以a[i]结尾的最长上升子序列的长度,则问题的解为 max{m[i],1≤i<=n}。初始化时,易得m[1]=1(以第一个元素为末尾元素时则最长序列即为a1),试想,在1右边,第一个大于a[1]的数,我们就可以把其接在a[1]后面形成一个更长的子序列,我们可以得到如下的递推方程:m[i]=max(m[i],max(m[j]+1|j<i且a[j]<a[i]})), 这个递推方程意思就是,m[i]的值,就是在i左边,即下标小于i,且a[j]的值小于a[i],最长的LIS的长度再加1,因为a[i]>a[j],所以a[j]一定可以接在a[j]后面形成一个更长的子序列 ,问题得解。

    通过对LIS问题的探索,我们对动态规划的概念终于不是一个模糊的影子了!回到原点,动态规划就是动态地解决问题,当然上面所谈论的LIS问题只是动态规划的一个简单应用,日常生活中我们外出时经常会使用到百度地图,高德地图等,自驾开车旅行时更是经常会使用到最短路径这一功能,假设没有如此强大的地图软件,其实求得最短路径这一过程也是动态规划。假设从起点到终点有很多个站点,首先我们找到从起点到每一个站点的距离,接下来计算从起点出发到某一个第二站点的距离(分别经过同一个或不同的第一站点),接着计算到第三个站点的距离(直接利用到第二个站点的最短距离),第四个,第五个,……最终求得从起点到终点的最短距离。通过动态地计算两地之间的最短路径,最终递推得出出发点到结束点的最短路径,将总问题分解为子问题不正是动态规划的精髓所在吗?

    动态规划实则是寻找解决问题的观察角度,而将其分治,使问题可以以递推的形式呈现,从而解决问题的思想。以上只是我对动态规划的浅薄之见,这种思想的广阔世界等着大家去探索!

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: