我想知道如何基于Levenshtein distance
生成一组类似的字符串(字符串编辑距离)。理想情况下,我喜欢传入一个源字符串(即用于生成与其类似的其他字符串的字符串),需要生成的字符串数量和作为参数的阈值,即字符串之间的相似性。生成的集应该大于阈值。我想知道我应该用Python
个包来实现这个目标吗?或者任何想法如何实现这个?
答案 0 :(得分:1)
我认为你可以用另一种方式来思考问题(逆转)。
k
。 例如,让我们说k = 2.并假设您拥有的edit modes是:
然后逻辑如下:
input = 'sittin'
for num in 1 ... n: # suppose you want to have n strings generated
my_input_ = input
# suppose the edit distance should be smaller or equal to k;
# but greater or equal to one
for i in in 1 ... randint(k):
pick a random edit mode from (delete, add, substitute)
do it! and update my_input_
如果您需要坚持使用预定义的字典,这会增加一些复杂性,但仍然可行。在这种情况下,编辑必须有效。
答案 1 :(得分:0)
大量借用@greeness answer中的伪代码,我想我会包括我以前对DNA序列使用的代码。
这可能不是您的确切用例,但我认为它应该很容易适应。
import random
dna = set(["A", "C", "G", "T"])
class Sequence(str):
def mutate(self, d, n):
mutants = set([self])
while len(mutants) < n:
k = random.randint(1, d)
for _ in range(k):
mutant_type = random.choice(["d", "s", "i"])
if mutant_type == "i":
mutants.add(self.insertion(k))
elif mutant_type == "d":
mutants.add(self.deletion(k))
elif mutant_type == "s":
mutants.add(self.substitute(k))
return list(mutants)
def deletion(self, n):
if n >= len(self):
return ""
chars = list(self)
i = 0
while i < n:
idx = random.choice(range(len(chars)))
del chars[idx]
i += 1
return "".join(chars)
def insertion(self, n):
chars = list(self)
i = 0
while i < n:
idx = random.choice(range(len(chars)))
new_base = random.choice(list(dna))
chars.insert(idx, new_base)
i += 1
return "".join(chars)
def substitute(self, n):
idxs = random.sample(range(len(self)), n)
chars = list(self)
for i in idxs:
new_base = random.choice(list(dna.difference(chars[i])))
chars[i] = new_base
return "".join(chars)
要使用此功能,您可以执行以下操作
s = Sequence("AAAAA")
d = 2 # max edit distance
n = 5 # number of strings in result
s.mutate(d, n)
>>> ['AAA', 'GACAAAA', 'AAAAA', 'CAGAA', 'AACAAAA']