1.最优子结构的概念,并从反面举例“哪些case不具备最优子结构”;
动态规划只能应用于有最优子结构的问题。最优子结构的意思是局部最优解能决定全局最优解(对有些问题这个要求并不能完全满足,故有时需要引入一定的近似)。简单地说,问题能够分解成子问题来解决。
最优子结构性质。如果问题的最优解所包含的子问题的解也是最优的,我们就称该问题具有最优子结构性质(即满足最优化原理)。最优子结构性质为动态规划算法解决问题提供了重要线索。
正反示例:
最短路径问题有以下最优子结构性质:如果一个节点x是到源节点ü的最短路径,同时又是到目的节点V的最短路径,则最短路径从u到 v是结合最短路径:u到x和x到v。
另一方面最长路径问题不具有最优子结构性质。 这里的最长路径是指两个节点之间最长简单路径(路径不循环)。 考虑下算法导论上面的例子:有两条最长的路径与Q到T:Q – > R – > T和Q – > S-> T。 不像最短路径,这些路径最长不具有最优子属性。 例如,最长路径q-> r-> t不是由q->r 和 r->t的组合 ,因为最长的路径从q至r为q-> s-> t->r
最优化原理:
1951年美国数学家R.Bellman等人,根据一类多阶段问题的特点,把多阶段决策问题变换为一系列互相联系的单阶段问题,然后逐个加以解决。一些静态模型,只要人为地引进“时间”因素,分成时段,就可以转化成多阶段的动态模型,用动态规划方法去处理。与此同时,他提出了解决这类问题的 “最优化原理”(Principle of optimality);“一个过程的最优决策具有这样的性质:即无论其初始状态和初始决策如何,其今后诸策略对以第一个决策所形成的状态作为初始状态的过程而言,必须构成最优策略”。简言之,一个最优策略的子策略,对于它的初态和终态而言也必是最优的。这个“最优化原理”如果用数学化一点的语言来描述的话,就是:假设为了解决某一优化问题,需要依次作出n个决策D1,D2,…,Dn,如若这个决策序列是最优的,对于任何一个整数k,1 < k < n,不论前面k个决策是怎样的,以后的最优决策只取决于由前面决策所确定的当前状态,即以后的决策Dk+1,Dk+2,…,Dn也是最优的。
最优化原理是动态规划的基础。任何一个问题,如果失去了这个最优化原理的支持,就不可能用动态规划方法计算。
2.理解子问题的重叠性,并说明“动态规划是如何避免重复子问题的重复计算”;
子问题重叠性质是指在用递归演算法自顶向下对问题进行求解时,每次产生的子问题并不总是新问题,有些子问题会被重复计算多次。动态规划算法正是利用了这种子问题的重叠性质,对每一个子问题只计算一次,然后将其计算结果保存在一个表格中,当再次需要计算已经计算过的子问题时,只是在表格中简单地查看一下结果,从而获得较高的效率。
动态规划在针对有很多重叠子问题的情况的最优解时有效。它将问题划分成一个个相似的子问题。为了避免多次解决这些子问题,子问题的结果都逐渐被计算并被保存,从简单的问题直到整个问题都被解决。因此,动态规划保存每一层递归时计算的到的的结果,因而不会在解决同样的问题时再花费时间。3.从理论上证明“动态规划”算法的正确性;
(1)考虑辅助数组,第一行与第一列肯定是正确的,这也很好理解,一个字符串和空串的最长公共子序列必然为0。
(2)如果s[1…i-1]和t[1…j-1]的最长公共子序列长度为length_0,那么可以分两种情况讨论
1)如果s[i]=t[j],那么最长公共子序列长度为length_0+1。
2)如果s[i]!=t[j],那么最长公共子序列要么是s[1…i]和t[1…j-1]的最长公共子序列length_1;要么是s[1…i-1]和t[1…j]的最长公共子序列length_2
(3)总之上述判断过程证明我们可以得到结果,但并没有证明结果是最长的,算法中引进了比较过程,时刻比较length_1和length_2的大小,只保留大的。这样就能保证最终获得的结果是最长的。
以下引自《算法导论》:
(1)LCS的最优子结构的证明:
设序列X=<x1, x2, …, xm>和Y=<y1, y2, …, yn>的一个最长公共子序列Z=<z1, z2, …, zk>,则:
a. 若xm=yn,则zk=xm=yn且Zk-1是Xm-1和Yn-1的最长公共子序列;
b. 若xm≠yn且zk≠xm ,则 Z是Xm-1和Y的最长公共子序列;
c. 若xm≠yn且zk≠yn ,则Z是X和Yn-1的最长公共子序列。
(其中Xm-1=<x1, x2, …, xm-1>,Yn-1=<y1, y2, …, yn-1>,Zk-1=<z1, z2, …, zk-1>。)
证明:(a)如果zk≠xm,那么可将Xm=Yn追加到Z的末尾,得到X和Y的一个长度为k+1的公共子序列,与Z是X和Y的最长公共子序列的假设矛盾。因此,必然有zk=xm=yn。这样,前缀Zk-1是Xm-1和Yn-1的一个长度为k-1的公共子序列。我们希望证明他是一个LCS。利用反证法,假设存在Xm-1和Yn-1的一个长度大于k-1的公共子序列W,则将xm=yn追加到W的末尾会得到X和Y的一个长度大于k的公共子序列,矛盾。
(b)如果zk≠xm,那么Z是Xm-1和Y的一个公共子序列。如果存在Xm-1和Y的一个长度大于k的公共子序列W,那么W也是Xm和Y的公共子序列,与Z是X和Y的最长公共子序列的假设矛盾。
(c)与情况b对称。
这说明了两个序列的LCS包含两个序列的前缀的LCS。因此LCS问题具有最优子结构性质。
(2)LCS重叠子性质:
由最长公共子序列问题的最优子结构性质可知,要找出X=<x1, x2, …, xm> 和Y=<y1, y2, …, yn>的最长公共子序列,可按以下方式递归地进行:当xm=yn时,找出Xm-1和Yn-1的最长公共子序列,然后在其尾部加上xm(=yn)即可得X和Y的一个最长公共子序列。当xm≠yn时,必须解两个子问题,即找出Xm-1和Y的一个最长公共子序列及X和Yn-1的一个最长公共子序列。这两个公共子序列中较长者即为X和Y的一个最长公共子序列。
由此递归结构容易看到最长公共子序列问题具有子问题重叠性质。例如,在计算X和Y的最长公共子序列时,可能要计算出X和Yn-1及Xm-1和 Y的最长公共子序列。而这两个子问题都包含一个公共子问题,即计算Xm-1和Yn-1的最长公共子序列。
在递归中,,通过限制条件限定了需要求解哪些子问题。当Xi=Yi时,我们可以而且应该求解子问题:Xi-1和Yj-1的一个LCS。否则应该求解两个子问题:Xi和Yj-1的一个LCS,Xi-1和Yj的一个LCS。