贪心算法和动态规划(2)

来源:互联网 发布:寻找淘宝客 编辑:程序博客网 时间:2024/06/12 23:28
贪心算法和动态规划(2)
                                                                                                                                                                                 ----by  C_xiaobao
2.动态规划
  上次讲贪心算法的时候,我是先用了一个引例,然后再退回到概念层面上来讲贪心算
法。但是这次,我要先讲动态规划算法基本思想,然后再以典型的01背包问题结束。
a.基本思想(参考百度百科):
动态规划算法通常用于求解具有某种最优性质的问题。在这类问题中,可能会有许多可行
解。每一个解都对应于一个值,我们希望找到具有最优值的解。动态规划算法与分治法
似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子
题的解得到原问题的解。与分治法不同的是,适合于用动态规划求解的问题,经分解得到
子问题往往不是互相独立的。若用分治法来解这类问题,则分解得到的子问题数目太多,
有些子问题被重复计算了很多次。如果我们能够保存已解决的子问题的答案,而在需要时
再找出已求得的答案,这样就可以避免大量的重复计算,节省时间。我们可以用一个表来
记录所有已解的子问题的答案。不管该子问题以后是否被用到,只要它被计算过,就将其
结果填入表中。这就是动态规划法的基本思路。具体的动态规划算法多种多样,但它们具
有相同的填表格式。

b.实现步骤:

                 (1)找出最优解的性质,并刻划其结构特征。

                 (2)递归地定义最优值。

                 (3)以自底向上的方式计算出最优值。

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

当然,这个步骤在现在看起来会比较唐突,接下来我们会以01背包问题为例,具体说

明。


          c.适用条件:

另外我想说:

(1).一个最优化策略的子策略总是最优的。等于你解决了一个大问题时,它的所有子问

题你也都有了最优解。

(2).以前的状态无法对直接影响未来的决策。

(3).之前讲到会保存子问题的答案,可以避免大量的运算,减少冗余。

以上的三个性质也即就是表明了我们的动态规划算法适用于解决“对应”(比如利用第

三个性质 就适用于子

问题复杂计算是具有冗余的问题)的问题。以上三个性质可以说是三个适用条件,用

书本上看不懂的表达分

别叫做:最优化原理、无后效性、子问题重叠性。

d.01背包问题:

有编号分别为a,b,c,d,e的五件物品,它们的重量分别是2,2,6,5,4,它们的价值分别是

6,3,5,4,6,现在给你个

承重为10的背包,如何让背包里装入的物品具有最大的价值总和?

首先呢我们需要定义一些表达式的含义(如下):

w[i]:第i个物体的重量;

p[i]:第i个物体的价值;

c[i][m]:前i个物物体放入承重为m的背包的最大价值;

c[i-1][m]:前i个物体放入承重为m的背包的最大价值;

c[i-1][m-w[i]]:前i-1个物体放入承重为m-w[i]的背包的最大价值;

OK,有了这些基础,我们就可以根据之前总结好的步骤来解州01背包问题了。

(1)找出最优解的性质,并刻画其结构特征

性质:要求出背包承重为10所能装的最大价值总和.当背包承重为小于10的时候,其最

优解应该是此问题最优解的子

(2)递归的定义最优值:

                                首先:c[i][m]=c[i-1][m] (当背包不能再装第i个物体时,那么

最大价值总和等前i-1个是相同的)

                             c[i][m]=max{c[i-1][m-w[i]]+pi , c[i-1][m]}(当背

包可以装第i个物体时,那么其最大价值总和是c[i-1][m-w[i]]+pi和 c[i-1][m]中

较大的那一个)

(3)以自底向上的方式计算最优值:

                          根据上面的转移方程,由低上上计算最优值

 (4)根据计算最优值时得到的信息,构造最优解。(下图来自:这里

nameweightvalue12345678910a26066991212151515b23033669991011c65000666661011d54000666661010e460006666666注意:此图应该由低向上,由左向右开阅读。即就是背包的容量看做是有1增长到

10的动态过程。此外,为了理解,前i件物品的试图放入背包顺序可以这样认为:

e,d,c,b,a.即就是e是第一个,d是第二个物体,,,,a是第五个物体。

比如:e2格表示当背包承重为2时,重量为4的e物体是不能放进去的。那么b2格

表示当背包承重2时,e,d,c都无法装入背包,b装入背包,价值为3.那么a2表

示,当背包承重为2时,e,d,c都无法装入背包,a,b可以装入,但是相比较a是最优

解。所以价值从3更新为6。

那么我们在来看a8=15(即就是c[5][8])是怎么得出来的。根据状态转移方程:

c[i][m]=max{c[i-1][m-w[i]]+pi , c[i-1][m]}我们知道要求出c[5][8],

我们需要先比较c[4][8]和c[4][6]+p[5](p[5]就是a的价值,a是第5个物体)由表可知:

c[4][8]=9;c[4][6]+p[5]=9+6=15;所以c[5][8]也就是a8的值为15.

这就是经典的01背包问题。大家感受一下动态规划的魅力。


当然,仅仅是这一点,对动态规划想要整体全面的了解还是不够的。可以参见以下两篇我的文章:
想要了解贪心算法:请点击这里
贪心算法和动态规划的对比认识:请点击这里










0 0