找到两组之间的邻近匹配对

时间:2011-12-22 09:46:48

标签: c++ algorithm data-structures

给定两组关键字,其中每个关键字都有开始和结束偏移(例如关键字“abc”从偏移23开始到结束于偏移25),我想有效地找到这些组之间的匹配对。 匹配对是set1中的关键字和set2中的关键字,其中一个关键字在另一个关键字结束后开始,但在一个关键字的结尾与另一个关键字的开头之间不超过MAX_PROXIMITY个字符。此外,每个关键字只能属于一对(匹配的关键字不能再用于其他匹配)。

2 个答案:

答案 0 :(得分:2)

您可以将其表示为二分图中的最大匹配。考虑两组顶点,并将第一组中所有顶点之间的边生成第二组中满足规则的所有顶点,即“一个关键字在另一个关键字结束后开始,但不超过MAX_PROXIMITY一个结尾与另一个结尾之间的字符“

准备好图表后,在二分图中运行最大匹配算法。 http://en.wikipedia.org/wiki/Matching_(graph_theory)#Maximum_matchings_in_bipartite_graphs

答案 1 :(得分:0)

您可以使用动态编程来解决此问题。

假设您有每组关键字按其开始的偏移量排序。 我们来定义

set1_keyword[i] # i-th keyword in the first set (ordered by the start offset)
set2_keyword[j] # same for the second set
max_pairs[i][j] # number of pairs in optimal assignment between keywords 1..i from the first set and keywords 1..j from the second set

当然max_pairs[n1][n2]是您问题的答案(n1n2分别是第一个和第二个关键字集的大小)

要计算max_pairs表,请使用以下公式

if (set1_keyword[i] matches set2_keyword[j])
    max_pairs[i][j] = max_pairs[i-1][j-1] + 1
else
    max_pairs[i][j] = max(max_pairs[i-1][j], max_pairs[i][j-1])

这基本上说如果你可以匹配你做的关键字,因为对于关键字1..i和1..j的问题,这是你能做的最好的。在另一种情况下(第i个和第j个关键字不匹配),您无法找到第i个和第j个关键字与某些不同关键字配对的解决方案。因此,在最优解决方案中,第i个关键字或第j个关键字应该是不配对的。 这基本上告诉我们要查看问题max_pairs[i-1][j](没有第i个关键字)或max_pairs[i][j-1](没有第j个关键字)的(已经计算的)解决方案,并选择两者中较好的一个。

如果按正确顺序计算此表,即

for (int i = 0; i < n1; ++i)
    for (int j = 0; j < n2; ++j)
        # compute max_pairs[i][j] here

算法将具有O(n1 * n2)复杂度,这比二分图(在O(n ^ 3)中运行)中的赋值问题更好

有关动态编程的更多信息,请参阅dynamic programming