Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.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_Sequence_Matching - Fatal编程技术网

Algorithm 对于无序序列匹配问题,哪种算法更好?

Algorithm 对于无序序列匹配问题,哪种算法更好?,algorithm,sequence,matching,Algorithm,Sequence,Matching,如果我有两个序列(例如字符串) 我想知道从b到a的最佳子串匹配(无序),例如: optimal (6 matched parts, 19 characters of a matched) b a DDFF -> DDFF (4,7) AA -> AA (0,1) 1122 -> 1122 (11,14) 1 D -> D (21) HH VV1VAA -> VV1VAA

如果我有两个序列(例如字符串)

我想知道从b到a的最佳子串匹配(无序),例如:

optimal (6 matched parts, 19 characters of a matched)
b         a
DDFF   -> DDFF     (4,7)
AA     -> AA       (0,1)
1122   -> 1122     (11,14)
1     
D      -> D        (21)
HH
VV1VAA -> VV1VAA   (15,20)
FE     -> FE       (8,9)
还有另一种解决方案,但不是最优的:

not optimal (8 parts matched, 19 characters of a matched)
b        a
DDFF  -> DDFF  (4,7)
AA    -> AA    (0,1)
1122  -> 1122  (11,14)
1     -> 1     (17)
D     -> D     (21)
HH
VV    -> VV    (15,16)
1     
VAA   -> VAA   (18,20)
FE    -> FE    (8,9)
什么样的算法更适合这个问题???(我需要最佳结果,性能至关重要)


谢谢。

有趣的问题,您可以使用Boyer-Moore(–Moore|u string|u search|算法)或KMP(–Morris–Pratt|u算法)或任何其他线性时间字符串搜索算法,用O(|a|b |+b| 2)来解决它

  • 对于每个b[0..i]ty,在字符串a中找到它(在O(|a |+i)中),直到你再也找不到它为止
  • 你知道你可以找到b[0..i],但不能找到b[0..i+1],所以你有一个匹配的b[0..i],然后继续b[i+1..i+1],b[i+1..i+2]
  • 在结束时,b的每个部分是否匹配,如果匹配,则尽可能大
总复杂度最多为和(O(| a |+i),i=0..b |)=O(|a |.| b |+| b | ^2),但如果在a中只能找到b的小子串,它可能会小得多

编辑:

上面的方法是贪婪的,不会最小化部分的数量,但我认为它会最大化匹配的字符总数。
关于最佳解决方案的思考:

  • 对于| b |的每一个| b | ^2子串,确定它是否可以在| a |中找到,并只保留它所对应的子串
  • 我们需要在这些字符串中找到一个子集,其中包含:
    • 它们之间没有重叠
    • 长度之和最大
    • 长度相等时,字符串的数量必须最小
求和很容易计算,因为一个非常简单的解决方案是只匹配大小为1的子字符串:那么长度是a和b之间的常用字母数

因此,如果我们将大小为1的子字符串b(甚至是不在a中的字母)添加到上面的匹配字符串集中,我们需要找到一个不重叠的b的最小集合覆盖

一般集合覆盖是NP完全的,但这里并没有重叠约束,这有帮助吗

我正在调查

事实上,NP完全:


您可能需要寻找近似算法……

如果我理解您的问题,您需要找到一组由两个给定字符串组成的非重叠公共子字符串,它们要么使公共子字符串的总长度最大化,要么使公共子字符串的数量最小化。我将提出以下启发式方法:找到两个字符串中最长的公共子字符串(LCS),删除它,然后重复。我不能证明这是最优的,但我有一个非常有效的算法

在你的例子中 AAACDDFFFEE11122VV1VAADD DDFFAA1121DHHV1VAAFE LCS=VV1VAA

AAACDDFFFEE1122DD DDFFAA1121DHHFE

LCS=DDFF

AAACFEE1122DD AA11221DHHFE

LCS=1122

AAACFEEDD 阿赫菲

诸如此类

算法如下 1) 使用基于后缀树的标准LCS算法 1.1构建两个串联字符串的后缀树,并使用唯一的终止符 1.2根据根植于其中的子树是否具有来自其中一个或两个字符串的叶子,用1,2或两者标记每个节点 1.3计算每个节点的管柱深度 1.4查找标记为1和2的字符串最深节点 2) 删除以该节点为根的子树,并更新其上节点的标签 3) 从1.4开始重复

当树没有标记为1和2的节点时,算法终止 1.1可在与两个字符串长度之和成比例的时间内完成 1.2、1.3和1.4只不过是树遍历 2如果正确实现了树,并且更新受LCS长度的限制,则移除时间应为常数 3又是一棵树的遍历,但它是一棵较小的树的遍历

这是一个优化,为了避免重复的树遍历,让我们添加步骤1.35:按字符串深度对具有两个标签的内部节点进行排序(在单独的数据结构中,树仍然存在)。现在可以扫描已排序的节点列表,执行2)并重复。有了这个优化,如果你能使用基数排序,它看起来像是线性时间的算法,你不能在一个渐进的意义上击败它


我希望这是正确的和足够清楚的,我相信你需要熟悉一下后缀树文献,然后它听起来很明显。我推荐丹·古斯菲尔德(Dan Gusfield)的《字符串、树和序列算法》(Algorithms on String,Trees and Sequences)一书,特别是第7.4节,如果您有问题,请告诉我。

您能重新表述您的问题吗?我知道a和b是问题输入的一部分(“从b到a无序匹配的最佳子字符串”),但子字符串也是输入的一部分吗?或者您正在寻找最长的(或任何)公共子序列?无需其他输入。LCS不是我想要的。在本例中,LCS将输出“DDFF1122VVVA”,b中的“AA”和“FE”将不属于LCS,因为LCS是订单问题。谢谢。我需要这个问题的最优解(我将我的问题改为更清楚地描述),重复子串搜索算法不会得到最优解。事实上,在第一个例子中,最优性问题并不清楚,我现在更明白了。我的(贪婪)方法在匹配字符总数上是最优的,但可能比“最优”方法有更多的部分。在问题陈述中,我仍然只看到两个例子。要求定义解决方案的总顺序是不是太过分了?匹配的字符数是否总是比部件总数更重要?如果你不清楚地定义这一点,就会有一些琐碎的解决方案(一个是将字符串视为多个字符集并输出交集,另一个极端是最长的公共子字符串)@piccolbo我想他想要的是最大化匹配字符的数量(多个字符集将给出该数量),在所有解决方案中
not optimal (8 parts matched, 19 characters of a matched)
b        a
DDFF  -> DDFF  (4,7)
AA    -> AA    (0,1)
1122  -> 1122  (11,14)
1     -> 1     (17)
D     -> D     (21)
HH
VV    -> VV    (15,16)
1     
VAA   -> VAA   (18,20)
FE    -> FE    (8,9)