找到最小的连接子串集

时间:2013-05-22 16:22:22

标签: algorithm set

让我们考虑一个查询集Q和一个更大的超集S.Q的每个元素都存在于S.目标是使用S中最小数量的(连通)“组件”来表达Q.

这是一个具体的例子: Q = {我爱法国和葡萄酒} S = {(我住在这里),(我爱你和她),(法国很美),(奶酪和葡萄酒)}

Q的解决方案可能: - “我住在这里”的“我” - 来自“我爱你和她”的“爱” - 来自“法国美丽”的“法国” - “和”来自“我爱你和她” - “奶酪和葡萄酒”中的“葡萄酒” 这导致5个“组件”,即“我”,“爱”,“法国”,“和”,“葡萄酒”

更好的解决方案是: - “我爱你”来自“我爱你和她” - 来自“法国美丽”的“法国” - “奶酪和葡萄酒”中的“和葡萄酒” 这导致了3个“组件”,即“我爱”,“法国”,“和葡萄酒” 这可能是这个例子的最佳解决方案。我们希望尽量减少这些“组件”。

有谁知道如何调用这种算法? 我搜索了文本解析,文本挖掘等,但我找不到合适的东西。

2 个答案:

答案 0 :(得分:1)

您所描述的内容听起来像set cover problem,其中您有一个主集(在您的情况下,查询)和一系列集(您的组件)可供选择,目标是覆盖每一个主集的元素。这个问题已得到很好的研究,但不幸的是它是NP难的,并且没有已知的多项式时间算法。此外,在最坏的情况下,集合覆盖的最佳多项式时间近似算法仅在真实解的O(log n)因子内。

如果您正在处理小型查询或少量组件,您可以通过列出所有子集并检查哪些子集有效来强制解决问题。但是,对于大型查询或大量组件,您不应期望有效地获得准确的答案。

希望这有帮助!

答案 1 :(得分:1)

我会将此问题描述为“最小间隔时间”;我不确定这是规范名称,但我不是第一个使用该词组的人。

有一个有效的算法有两个阶段。在第一阶段,确定源中出现的查询的最大子字符串。对于每个这样的子串,输出第二阶段的间隔。在第二阶段,通过重复选择覆盖最低未覆盖位置的最高端点的区间来找到最小基数覆盖。

在你的例子中

Q=(I love France and wine)
S={(I live here), (I love you and her), (France is beautiful), (cheese and wine)}

间隔是,从一个,(1,2)“我爱”,(3,3)“法国”,(4,5)“和葡萄酒”索引。哎呀,现在第二阶段是微不足道的。假设改为

Q=(a b c d)
S={(a b), (b c), (c d)}
然后,间隔是(1,2)“a b”,(2,3)“b c”,(3,4)“c d”。最低的未覆盖是1;我们采取(1,2)。最低的未覆盖是3;我们将(3,4)超过(2,3)因为4> 3。

编辑添加:

瓶颈很可能是第一阶段。如果这是一个问题,那就有一个算法:构造一个包含源句的suffix tree。然后,根据查询字符串遍历树。除非查询在源代码中逐字显示,否则您最终会尝试关注不存在的链接;在这种情况下,当前最大间隔结束,您需要按照后缀链接,直到您可以再次进展。 (计算生物学家,我在描述哪种算法?)