给定一组长度相同的二进制字符串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
答案 0 :(得分:3)
扩展Egor的评论:
想象一下,你有一个图G
,它为S
中的每个字符串都有一个顶点。现在,对于每对顶点v1
,v2
找到相应字符串s1
,s2
之间的汉明距离。如果它超过d
,请在G
和v1
之间的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而不是更快的算法?后者更复杂,不会扩展你的影响力。)