查找相距很远的最大大小的字符串集

时间:2013-04-27 22:41:26

标签: python algorithm

给定一组长度相同的二进制字符串S,找到S的最大尺寸子集S'的快速方法是什么,S'中每对字符串之间的汉明距离至少为d?

以下函数计算两个弦之间的汉明距离。

def hamdist(str1, str2):
    """Count the # of differences between equal length strings str1 and str2"""
    if (len(str1) != len(str2)):
        print str1, str2, "Length mismatch!"
        quit()
    diffs = 0
    for ch1, ch2 in itertools.izip(str1, str2):
        if ch1 != ch2:
            diffs += 1
    return diffs

2 个答案:

答案 0 :(得分:3)

扩展Egor的评论:

想象一下,你有一个图G,它为S中的每个字符串都有一个顶点。现在,对于每对顶点v1v2找到相应字符串s1s2之间的汉明距离。如果它超过d,请在Gv1之间的v2添加边距。

现在,您希望找到S的最大子集,使得此最大子集中的每对字符串之间的汉明距离至少为d。我们刚构建的图上的相应问题是找到最大的顶点集,使得该集合中的每个顶点都连接到该集合中的每个其他顶点。

这是Maximum Clique problem。如果您点击维基百科文章的链接,您会发现解决此问题的最着名算法在O(1.2599^n)时间内运行,这是指数级的,因此不会很快。如果您可以快速解决问题(也就是说,在多项式时间内),那么您可以使用此对应关系解决多项式时间中的最大Clique问题,因此没有快速解决您的问题。

答案 1 :(得分:2)

正如福尔克所说,为了证明这个问题是NP难的,我们需要从 NP 问题中减少。我将使用寻找独立集合的问题(即在补图中找到一个集团)。

我的减少有两个阶段。第一阶段的输出是具有非二进制字母表的通用实例。第二阶段的输出使用二进制字母表。设G =(V,E)是我们试图找到一个大的独立集的图。第一阶段的输出是| V |长度的话| E |。设e =(v,w)为i th 边缘。每个单词的i th 位置的字母都是不同的,除了对应于v和w的单词,它们在那里共享一个字母。因此,字母表的大小为| V | - 1.当且仅当它们的单词处于最大距离时,两个顶点是不相邻的,因此我们将距离阈值设置为| V |。

在第二阶段,我们用| V |中的一个替换每个字母 - 1个长度的字| V | - 1具有1“1”和(| V | - 2)“0”s并且距离阈值加倍为2 | V |。

为了解决小实例,我建议使用Sam减少到最大团体问题并运行指数时间Bron–Kerbosch algorithm来枚举所有最大派系,从中可以选择最大值。 (为什么B-K而不是更快的算法?后者更复杂,不会扩展你的影响力。)