有人可以在动态编程中解释最佳子结构吗?

时间:2015-11-06 09:16:29

标签: algorithm data-structures dynamic-programming

我一直在努力理解动态编程,我理解的是DP有两个部分。 的 1。最优的子结构 2.重叠子问题

我理解第二个,但也无法获得第一个。

有人可以用简单的英语解释一下易于理解的例子吗?

4 个答案:

答案 0 :(得分:14)

最优子结构意味着,对n大小问题的任何最优解决方案都是基于在考虑n' < n元素时针对同一问题的最佳解决方案。

这意味着,在针对大小为n的问题构建解决方案时,您会将问题拆分为较小的问题,其中一个问题的大小为n'。现在,您只需要考虑n'的最优解,而不是所有可能的解决方案,基于最佳子结构属性。

一个例子是knapsack problem

D(i,k) = min { D(i-1,k), D(i-1,k-weight(i)) + cost(i) }

此处的最优子结构假设D(i,k)只能检查D(i-1,k)的最优解,而不考虑最优解。

不适用的例子是Vertex Cover problem

如果你有一个图G =(V,E),假设你有一个子图G'=(V',E[intersection]V'xV')的最佳解决方案,V' <= V - G的最佳解决方案没有由G' /

的最佳解决方案组成

答案 1 :(得分:4)

另一个很好的例子是在图中每对顶点之间找到最短简单路径,并在每对顶点之间找到最长简单路径之间的区别。 (&#34;简单&#34;意味着路径上的任何顶点都不能被访问两次;如果我们不将这个约束放在问题的最长版本中,那么我们可以只要图表包含一个循环,就会获得无限长的路径。)

Floyd-Warshall algorithm可以通过利用如下事实来有效地计算第一个问题的答案:如果从u到v的路径最短,那么对于此路径上的任何顶点x,必须是从u到x的子路径,以及从x到v的子路径,也是最短的。 (假设相反的是&#34;最短的路径x&#34;从u到v的路径,使得从u到x的子路径不是最短的:那么它可以找到从u到x的其他一些较短的路径 - 这也可用于使从u到v的整体路径缩短相同的量,因此原始的u-to-v路径毕竟不可能是最短的路径。)这意味着当寻找最短的u-to-v路径时,算法只需要考虑在其他顶点对之间的最短可能(即最佳)子路径中构建它 - 而不是从更大的顶点开始所有此类子路径的数量。

相反,考虑确定图中任意两个顶点之间的最长简单路径的问题。同样正确的是,如果从u到v的最长路径经过某个顶点x,那么从u到x,从x到v的子路径也必然也是最长的?不幸的是:很可能是从u到x的最长路径在其内部使用了从x到v的最长路径所需的一些顶点,这意味着我们不能简单地将这两条路径粘合在一起以获得从u到v。

的最长简单路径

作为一般规则,我们始终可以“绕过”#34;通过选择使用要解决的子问题的足够详细的定义来解决这个问题:在这种情况下,我们可以要求两个给定顶点u和v之间的最长路径,而不是要求两个给定顶点u和v之间的最长路径。 仅使用来自给定集合S 的顶点。以前我们可以构建一个带有两个参数的函数shortest(u, v),我们现在必须构建一个函数longest(u, v, S),它需要三个参数;然后可以使用longest(u, v, V)计算2个顶点u和v之间的总体最长路径,其中V是图的整个顶点集。通过这个新的定义,现在再次可以通过仅将最优解决方案与子问题相结合来生成最佳解决方案,因为我们可以确保我们只尝试将由子问题产生的路径粘合在一起集是不相交的。我们现在可以正确地确定从u到v的最长路径,该路径仅使用S中的顶点,即longest(u, v, S),通过计算S中所有顶点x的最大值,以及所有分区方式S- {x}分为longest(u, x, A) + longest(x, v, B)的两个子集A和B.

不幸的是,现在有一些指数的子问题要解决,因为一组n个顶点可以用2 ^(n-1)种不同的方式进行划分。 (刚才描述的算法对于这个问题来说不是最有效的DP,但即使是效率最高的已知DP仍然在其运行时间内具有这个指数因子。)设计DP算法的挑战总是找到一种定义子问题的方法这导致足够不同的子问题(理想情况下,只有多项式),同时仍保持重叠子问题和最佳子结构的两个属性。

答案 2 :(得分:0)

简单来说:“最优性原则在解决优化问题时必须解决子问题,子问题的解决方案将成为优化问题的一部分”,如果问题可以解决通过最优子问题解决意味着它包含最优子结构。

示例:假设在图表中,源顶点是s,目标是d。 我们必须找到最短的(s,d)

    graph is
                a        g
                b   e    h                d
    s           c   f    i
                d   

length(s,a)=14
length(s,b)=10
length(s,c)=1
length(s,d)=6
length(c,b)=1

注意:(s,e)或(s,f)没有直接边缘。 在考虑为此找到一个算法时,如果我们正在编写一个优先级队列结构,它将以最少的总PATH_Length遍历。 我们将从源顶点分配每个顶点PATH_LENGTH。

如果新的path_length ,我们将继续将path_length分配给相邻的顶点。现有路径长度。

Example : Len(s,b) > Len(s,a)+Len(a,b);
               reset len(s,b)=2;

来自S的相邻节点创建路径以获得最小路径长度而不管目标节点如何,因为它们正在构建导致解决方案的子结构

答案 3 :(得分:-1)

基本动态规划可以应用于优化问题。优化问题可以有很多解决方案,每个解决方案都有一个值,我们希望找到一个具有最佳(最大值或最小值)值的解决方案。我们称这种解决方案为该问题的最佳解决方案。这些优化问题称为“最佳子结构”。
“矩阵链乘法” 算法一样,我们选择与矩阵括号相关的成本的最小值。具有最小值的解决方案是此处问题的最佳解决方案。

                M[i,j] =   min    {M[i,k] + M[k+1,j] + (P(i-1) * P(k) * P(j))}
                          i<= k <j