Algorithm 如何计算最长公共子序列的数目

Algorithm 如何计算最长公共子序列的数目,algorithm,lcs,Algorithm,Lcs,我试图计算两个字符串之间可能存在的最长子序列的数量 e、 g。 字符串X=“efgefg”; 字符串Y=“efegf” 输出:最长公共序列数为:3 (即:efeg、efef、efgf-这不需要通过算法计算,此处仅显示用于演示) 我已经在O(| X |*| Y |)中,基于这里的一般思想,使用动态编程实现了这一点 有人能想出一种方法来更有效地使用运行时进行计算吗 --根据Jason的评论进行编辑。我不知道,但这里有一些大声思考的尝试: 我能够构造的最坏情况是,最长公共子序列的指数数为-2**(0.

我试图计算两个字符串之间可能存在的最长子序列的数量

e、 g。 字符串X=“efgefg”; 字符串Y=“efegf”

输出:最长公共序列数为:3 (即:efeg、efef、efgf-这不需要通过算法计算,此处仅显示用于演示)

我已经在O(| X |*| Y |)中,基于这里的一般思想,使用动态编程实现了这一点

有人能想出一种方法来更有效地使用运行时进行计算吗


--根据Jason的评论进行编辑。

我不知道,但这里有一些大声思考的尝试:

我能够构造的最坏情况是,最长公共子序列的指数数为-2**(0.5 | X |):

X = "aAbBcCdD..."
Y = "AaBbCcDd..."
其中最长的公共子序列正好包括{A,A}中的一个,正好包括{B,B}中的一个,等等。。。(吹毛求疵:如果你的字母表限制在256个字符以内,最终会崩溃——但2**128已经是一个巨大的数字了。)

但是,您不必生成所有子序列来计算它们。
如果你有O(| X |*| Y |),你已经比那更好了!我们从中了解到,任何比您更好的算法都不能试图生成实际的子序列

最长的公共子序列问题是一个研究得很好的CS问题


您可能想在这里阅读:

首先,我们知道,除非强指数时间假设失败,否则在O(n2-ε)时间内无法找到长度为n的两个序列的任何最长公共子序列,请参见:

这几乎意味着您无法计算如何在O(n2-ε)时间内将公共子序列与输入序列对齐的方法的数量。 另一方面,可以在O(n2)时间内计算这种对齐方式的数量。通过所谓的四次加速,也可以在O(n2/log(n))时间内计算它们

现在真正的问题是,如果你真的想计算这个,或者你想找到不同子序列的数量?恐怕后者是一个P-完全计数问题。至少,我们知道,计算规则语法可以生成的具有给定长度的序列的数量是#P-完全的:

S.Kannan、Z.Sweedyk和S.R.Mahaney。计数 以及随机生成正则语言中的字符串。 在ACM-SIAM离散算法研讨会上 (苏打水),第551-557页,1995年

这是一个类似的问题,从这个意义上说,计算规则语法生成给定长度序列的方法的数量是一个微不足道的动态规划算法。但是,如果您不想区分产生相同序列的代,那么问题将从简单变为极其困难。我的自然猜想是,序列对齐问题也是如此(最长公共子序列、编辑距离、最短公共超弦等)

因此,如果您想计算两个序列的不同子序列的数量,那么您当前的算法很可能是错误的,任何算法都无法在多项式时间内计算,除非p=NP(以及更多…。

最佳解释(带代码)我发现:


这些看起来是子序列,而不是子字符串。请澄清。我不确定我是否理解你的计算。什么规则使efeg、efef、efgf都是有效的解决方案?我想你不能重新排列字符的顺序,只能删除一些?这两个字符串是否应该是完全通用的,因此您可能会有“X=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa。您不能重新排列顺序,但可以删除字母。在你的例子中答案是0。对于X=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa?有一个长度为0的常见子序列是最长的。请参见,请在此处详细说明您的答案,而不是简单地包含外部链接。虽然这可以从理论上回答问题,但请在此处包含答案的基本部分,并提供链接以供参考。