多序列的最长公共子序列

为了找到M = 2序列最长的研究,我做了很多研究,但我想弄清楚如何对M≥2序列进行研究

我被赋予N和M:M序列,具有N个独特元素。 N是{1 – N}的集合。 我已经考虑过动态编程方法,但我仍然对如何实际合并它感到困惑。

输入示例

5 3 5 3 4 1 2 2 5 4 3 1 5 2 3 1 4 

这里可以看到最大序列

 5 3 1 

预期产出

 Length = 3 

一个简单的想法。

对于1N之间的每个数字i ,计算最后一个数字为i的最长子序列。 (我们称之为a[i]

为此,我们将从头到尾迭代第一个序列中的数字i 。 如果a[i] > 1 ,那么数字j使得在每个序列中它出现在i之前。
现在我们可以检查j所有可能值和(如果先前条件成立)做a[i] = max(a[i], a[j] + 1)

作为最后一位,因为j在第一序列中出现在i之前,这意味着已经计算a[j]

 for each i in first_sequence // for the OP's example, 'i' would take values [5, 3, 4, 1, 2], in this order a[i] = 1; for each j in 1..N if j is before i in each sequence a[i] = max(a[i], a[j] + 1) end end end 

如果你事先计算位置矩阵,那就是O(N^2*M)

既然你有独特的元素,那么@Nikita Rybak的答案是可以接受的,但是既然你提到了动态编程,那么当你有两个以上的序列时,你可以使用DP:

 dp[i, j, k] = length of longest common subsequence considering the prefixes a[1..i], b[1..j], c[1..k]. dp[i, j, k] = 1 + dp[i - 1, j - 1, k - 1] if a[i] = b[j] = c[k] = max(dp[i - 1, j, k], dp[i, j - 1, k], dp[i, j, k - 1]) otherwise 

要获得实际的子序列,请使用从dp[a.Length, b.Length, c.Length]开始的递归函数,并基本上反转上述公式:如果三个元素相等,则回溯到dp[a.Length - 1, b.Length - 1, c.Length - 1]并打印字符。 如果不是,则根据上述值的最大值回溯。

您可以查看“ 用于查找常见DNA子序列的新确定性算法的设计 ”论文。 您可以使用此算法构建DAG(第8页,图5)。 从DAG中,读取最大的常见不同子序列。 然后使用M的值尝试动态编程方法,以确定每个序列需要构建多少DAG。 基本上使用这些子序列作为键并将相应的序列号存储在找到它的位置,然后尝试找到最大的子序列(可以大于1)。