Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 最长公共子序列递归求解中记忆化的优势_Algorithm_Recursion_Dynamic Programming_Memoization - Fatal编程技术网

Algorithm 最长公共子序列递归求解中记忆化的优势

Algorithm 最长公共子序列递归求解中记忆化的优势,algorithm,recursion,dynamic-programming,memoization,Algorithm,Recursion,Dynamic Programming,Memoization,我在读一篇关于在解决最长公共子序列问题的文章,其中有两种解决方案,一种是递归的,另一种是通过二维数组的DP。DP解决方案在ONM时间内完成,而递归解决方案在O2^N时间内完成 递归解决方案的主要问题是子序列的重叠,如图所示。但是,如果我将每一对存储在一个散列中,以便下次函数递归需要该值时,它可以直接从散列中获取该值,而不是进一步递归。那么,这种添加将在多大程度上提高效率?它会到ONM吗 第二,为什么递归解会产生O2^N时间?如何找出像这样的递归函数的复杂性,或者找到斐波那契序列的递归函数,等等?

我在读一篇关于在解决最长公共子序列问题的文章,其中有两种解决方案,一种是递归的,另一种是通过二维数组的DP。DP解决方案在ONM时间内完成,而递归解决方案在O2^N时间内完成

递归解决方案的主要问题是子序列的重叠,如图所示。但是,如果我将每一对存储在一个散列中,以便下次函数递归需要该值时,它可以直接从散列中获取该值,而不是进一步递归。那么,这种添加将在多大程度上提高效率?它会到ONM吗


第二,为什么递归解会产生O2^N时间?如何找出像这样的递归函数的复杂性,或者找到斐波那契序列的递归函数,等等?

是的,使用散列将使它成为ONM。在本例中,该过程称为yes,不带r。只要确保不使用所选语言提供的实际hashmap容器,将其设置为一个简单的矩阵:如果当前对的值为-1,则递归计算它,否则假设它已计算并返回它

至于你的第二个问题,你可以用数学的方法来得到最佳的边界,或者像你的链接那样在纸上画出来,从而得到足够好的边界:

                f(n)
               /    \
         f(n-1)      f(n-2)
        /     \        
  f(n-2)       f(n-3)
          ...
这足以归纳地表明它将是O2^n:树的高度为n,在每个节点上,有两个递归调用,将问题从大小n减少到大小n-1,即O2^n-1。原来的问题是O2^n


请注意,说斐波那契是O2^n并不是错误的,但你可以用其他数学方法得到一个更紧的界。

是的,使用散列将使其成为ONM。在本例中,该过程称为yes,不带r。只要确保不使用所选语言提供的实际hashmap容器,将其设置为一个简单的矩阵:如果当前对的值为-1,则递归计算它,否则假设它已计算并返回它

至于你的第二个问题,你可以用数学的方法来得到最佳的边界,或者像你的链接那样在纸上画出来,从而得到足够好的边界:

                f(n)
               /    \
         f(n-1)      f(n-2)
        /     \        
  f(n-2)       f(n-3)
          ...
这足以归纳地表明它将是O2^n:树的高度为n,在每个节点上,有两个递归调用,将问题从大小n减少到大小n-1,即O2^n-1。原来的问题是O2^n


请注意,说斐波那契是O2^n并不是错误的,但你可以用其他数学方法得到一个更紧的界。

这很有趣。想象一下,我正在使用Python中的字典或Perl中的哈希之类的东西。使用二维数组比任何一种都有什么优势?@Cupidvogel-我不知道这些语言是如何实现字典的,但有两种方法:通常使用红黑树或AVL,这会增加日志大小因子,或者使用实际的哈希函数,平均为O1,但在最坏的情况下,它可能会开启,即使在平均水平上,它也会有开销。无论哪种方式,这都比检查和写入矩阵的条目要慢。对。那很酷。但是关于改进,你能证明记忆将把复杂性降低到ONM吗?@Cupidvogel-是的:参数对x,y的每个函数调用只计算一次值,然后保存它。对于相同参数的后续调用将检查它是否是使用矩阵计算的,如果是,则返回该值。在迭代解中,你需要访问DP矩阵中的DP_数组[x,y],它也是O1,因此这两个数组在复杂度方面是等价的。@Cupidvogel-一般来说,答案也是非常笼统的:使用math:P。有时像我用斐波那契那样画递归树会让它变得明显,其他时候可能不会。很多时候,大师们都会用谷歌搜索它。其他时候不会,你需要其他的定理。恐怕无法给出一般性的答案,这取决于实际的递归函数。这很有趣。想象一下,我正在使用Python中的字典或Perl中的哈希之类的东西。使用二维数组比任何一种都有什么优势?@Cupidvogel-我不知道这些语言是如何实现字典的,但有两种方法:通常使用红黑树或AVL,这会增加日志大小因子,或者使用实际的哈希函数,平均为O1,但在最坏的情况下,它可能会开启,即使在平均水平上,它也会有开销。无论哪种方式,这都比检查和写入矩阵的条目要慢。对。那很酷。但是关于改进,你能证明记忆将把复杂性降低到ONM吗?@Cupidvogel-是的:参数对x,y的每个函数调用只计算一次值,而
n保存它。对于相同参数的后续调用将检查它是否是使用矩阵计算的,如果是,则返回该值。在迭代解中,你需要访问DP矩阵中的DP_数组[x,y],它也是O1,因此这两个数组在复杂度方面是等价的。@Cupidvogel-一般来说,答案也是非常笼统的:使用math:P。有时像我用斐波那契那样画递归树会让它变得明显,其他时候可能不会。很多时候,大师们都会用谷歌搜索它。其他时候不会,你需要其他的定理。恐怕无法给出一般性的答案,这取决于实际的递归函数。