我的问题是NP-complete,但是,我试图找到至少一个稍微快一点的字符串搜索功能或模块,这可能有助于减少与现在相比的一些计算时间。任何建议将不胜感激。
连接(尽可能长的)超级字符串是:
AGGAGTCCGCGTGAGGGAGGTGTAGTGTAGTGG
以下代码在16米内产生最短的超弦:
CCGTAGGTGGAGT
import itertools as it
def main():
seqs = ['AGG', 'AGT', 'CCG', 'CGT', 'GAG', 'GGA', 'GGT', 'GTA', 'GTG', 'TAG', 'TGG']
seq_perms = [''.join(perm) for perm in it.permutations(seqs)]
for i in range(0, len(''.join(seqs))):
seq_perms = [''.join(perm)[:i] for perm in it.permutations(seqs)]
for perm in seq_perms:
if all(perm.find(seq) != -1 for seq in seqs) == True:
print 'Shortest superstring containing all strings:\n{}'.format(perm)
return
if __name__ == '__main__':
main()
任何在我的系统上花费更少时间完成的重构都将被标记为已解决。
答案 0 :(得分:48)
我应用了Dijkstra算法(宽度搜索)并有一个解决方案,在不到一秒的时间内给出了这个任务的答案。我在内存使用方面对它进行了一些优化,但我认为对于算法来说,这是一种比其他答案更好的方法。除非我们内存不足,否则这应该是一个更好的解决方案。
from collections import defaultdict
def dijkSuperstring(originalSeqs):
paths = defaultdict(set)
paths[0] = { '' }
while paths:
minLength = min(paths.keys())
while paths[minLength]:
candidate = paths[minLength].pop()
seqAdded = False
for seq in originalSeqs:
if seq in candidate:
continue
seqAdded = True
for i in reversed(range(len(seq)+1)):
if candidate.endswith(seq[:i]):
newCandidate = candidate + seq[i:]
paths[len(newCandidate)].add(newCandidate)
if not seqAdded: # nothing added, so all present?
return candidate
del paths[minLength]
print dijkSuperstring(
[ 'AGG', 'AGT', 'CCG', 'CGT', 'GAG', 'GGA', 'GGT', 'GTA', 'GTG', 'TAG', 'TGG' ])
我也尝试使用随机序列作为输入:
seqs = [ ''.join(random.choice('GATC')
for i in range(3))
for j in range(11) ]
print dijkSuperstring(deqs)
我很快发现解决时间在很大程度上取决于结果的大小(!)而不是输入的大小(所以它是不可预测的)。这并不太令人惊讶,但它使得比较不同算法有点困难,因为其他算法不一定也具有此属性。特别地,来自OP的序列集似乎构成相对轻量级的问题。其他一组包含3个字符的11个序列更难解决。
所以我做了一些统计测量;我解决了1000组8个序列。这是我为3和4个字符的序列做的。然后我将持续时间分为100组(从0到最高持续时间等间隔)并计算每组中有多少人。为了使图表平滑,我总是使用三个相邻组的总和。
下面的图表显示了两个这样的实验,使用我的算法的早期(非优化)版本执行(但曲线的形状与现在相同);我做了两次,至少知道图中的一个奇怪的沟渠是否有原因或只是纯粹的机会。
我有兴趣看到其他算法的相同类型输入的类似图表。这可能很有趣,因为我的算法显然存在内存问题。解决11个3个字符的序列由于内存耗尽而使我的机器多次停顿,因此即使它较慢,使用另一种算法也是有意义的。
答案 1 :(得分:8)
这应该这样做。
import itertools as it
SEQUENCES = ['AGG', 'AGT', 'CCG', 'CGT', 'GAG', 'GGA', 'GGT', 'GTA', 'GTG', 'TAG', 'TGG']
LONGEST_SUPERSTRING = ''.join(SEQUENCES)
def find_shortest_superstring():
current_shortest = LONGEST_SUPERSTRING
trim = len(current_shortest)-1
seen_prefixes = set()
for perm in it.permutations(SEQUENCES):
candidate_string = ''.join(perm)[:trim]
if candidate_string in seen_prefixes:
continue
seen_prefixes.add(candidate_string)
while is_superstring(candidate_string):
current_shortest = candidate_string
candidate_string = candidate_string[:-1]
trim = len(current_shortest)-1
return current_shortest
def is_superstring(s):
return all(seq in s for seq in SEQUENCES)
def main():
print 'Searching for shortest superstring containing all strings.'
ss = find_shortest_superstring()
print 'Found shortest superstring containing all strings:\n{}'.format(ss)
if __name__ == '__main__':
main()
代码运行大约需要15秒,并产生以下输出:
Searching for shortest superstring containing all strings.
Found shortest superstring containing all strings:
CCGTAGGTGGAGT
答案 2 :(得分:1)
仅回溯,但始终先检查大多数重叠。在得到一个好的候选答案之后,当当前路径导致一个字符串的长度等于或大于该候选答案时,我们就不必再沿这个路径走了。
在我的Jupyter笔记本中进行了测试。它似乎比这里的其他两个答案要快得多(11/18/2018)
def shortestSuperstring(A):
"""
:type A: List[str]
:rtype: str
"""
if len(A)==1:
return A[0]
dic={}
for i in xrange(len(A)):
for j in xrange(len(A)):
if i!=j:
ol=0
for k in xrange(1,min(len(A[i]),len(A[j]))):
if A[j][:k]==A[i][-k:]:
ol=k
dic[(i,j)]=ol
if max(dic.values())==0:
return "".join(A)
else:
ret="".join(A)
l=len(ret)
stack=[]
for i,wd in enumerate(A):
tmp=set(range(len(A)))
tmp.remove(i)
stack.append((wd,i,tmp))
while stack:
ans,cur,remain=stack.pop()
if len(ans)<l:
if not remain:
ret=ans
l=len(ret)
else:
tmp=[[dic[cur,idx],idx] for idx in remain] # [#overlap,idx]
tmp.sort()
for ol,idx in tmp:
nans=ans+A[idx][ol:]
nremain=set(remain)
nremain.remove(idx)
stack.append((nans,idx,nremain))
return ret
问题中的测试用例需要L
1.93 s ± 160 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
运行并给出答案:
'CCGTGGTAGGAGT'
其他一些测试用例(更长的字符串,开始击败其他两种方法,大约需要1到5秒):
****************************************************************************************************
case:
['mftpvodataplkewcouz', 'krrgsoxpsnmzlhprsl', 'qhbfymytxzbmqma', 'hunjgeaolcuznhpodi', 'kewcouzbwlftz', 'xzbmqmahunjgeaolcu', 'zlhprslqurnqbhsjr', 'rrgsoxpsnmzlhprslqur', 'diqukrrgsoxpsnmz', 'sjrxzavamftpvoda']
****************************************************************************************************
ans: qhbfymytxzbmqmahunjgeaolcuznhpodiqukrrgsoxpsnmzlhprslqurnqbhsjrxzavamftpvodataplkewcouzbwlftz
****************************************************************************************************
case:
['cedefifgstkyxfcuajfa', 'ooncedefifgstkyxfcua', 'assqjfwarvjcjedqtoz', 'fcuajfassqjfwarvjc', 'fwarvjcjedqtozctcd', 'zppedxfumcfsngp', 'kyxfcuajfassqjfwa', 'fumcfsngphjyfhhwkqa', 'fassqjfwarvjcjedq', 'ppedxfumcfsngphjyf', 'dqtozctcdk']
****************************************************************************************************
ans: zppedxfumcfsngphjyfhhwkqaooncedefifgstkyxfcuajfassqjfwarvjcjedqtozctcdk
****************************************************************************************************
case:
['ekpijtseahvmprvefkgn', 'yyevvcmeekpijtseahvm', 'vsfcyyevvcmeekp', 'xwmkoqhxvrovlmmvsfcy', 'cmeekpijtseahvmpr', 'oqhxvrovlmmvsfcyy', 'zpuemtclxbxwsypfxevx', 'clxbxwsypfxevxw', 'fkgnjgdvfygnlckyiju', 'xevxwmkoqhxvrovlmm']
****************************************************************************************************
ans: zpuemtclxbxwsypfxevxwmkoqhxvrovlmmvsfcyyevvcmeekpijtseahvmprvefkgnjgdvfygnlckyiju
****************************************************************************************************
case:
['ppgortnmsy', 'czmysoeeyugbiylso', 'nbfzpppvhbjydtx', 'rnzynedhoiunkpon', 'ornzynedhoiunkpo', 'ylsomoktkyfgljcf', 'jtvkrornzynedhoiunk', 'hvhhihwdffmxnczmyso', 'ktkyfgljcfbkqcpp', 'nzynedhoiunkponbfz', 'nedhoiunkponbfzpppvh']
****************************************************************************************************
ans: hvhhihwdffmxnczmysoeeyugbiylsomoktkyfgljcfbkqcppgortnmsyjtvkrornzynedhoiunkponbfzpppvhbjydtx
****************************************************************************************************
case:
['amefulhsdgvjvoab', 'giqxpqszaitzfzvtalx', 'cyqeolfgkihssycmiodg', 'glhhcfuprwazet', 'cmiodgiqxpqszaitzf', 'lhsdgvjvoabdviglhhcf', 'ssycmiodgiqxpqsza', 'bxtdqnamefulhsdg', 'namefulhsdgvjvo', 'ihssycmiodgiqxp', 'itzfzvtalxfybxtdqn']
****************************************************************************************************
ans: cyqeolfgkihssycmiodgiqxpqszaitzfzvtalxfybxtdqnamefulhsdgvjvoabdviglhhcfuprwazet
****************************************************************************************************
case:
['yobbobwqymlordokxka', 'jllfoebgbsrguls', 'rgulsnatnpuuwiyba', 'ordokxkamymamofefr', 'wqymlordokxkamy', 'fycxifzsjllfoebgbsrg', 'lordokxkamymamofe', 'kxkamymamofefrmfycx', 'frmfycxifzsjllf', 'srgulsnatnpuuwiy']
****************************************************************************************************
ans: yobbobwqymlordokxkamymamofefrmfycxifzsjllfoebgbsrgulsnatnpuuwiyba
****************************************************************************************************
case:
['jnbbbbsczcscxawcze', 'bsczcscxawczeumyyr', 'lyofvbhvjmquhkgz', 'quhkgzyzdwtjnbbb', 'kgzyzdwtjnbbbbsczc', 'uouxnfplptpkgnronf', 'pqgyfqglyofvbhv', 'kgnronftgswvpqgy', 'marvhdxtbmkcpnli', 'qgyfqglyofvbhvjmquhk', 'xtbmkcpnliz']
****************************************************************************************************
ans: marvhdxtbmkcpnlizuouxnfplptpkgnronftgswvpqgyfqglyofvbhvjmquhkgzyzdwtjnbbbbsczcscxawczeumyyr
****************************************************************************************************
case:
['qrwpawefqzfjsan', 'jsanzdukfkdlmyox', 'neaxnkedjxbpgsyq', 'nqjvzryhfjdsxmwolwo', 'hfjdsxmwolwomeeewvi', 'lmyoxbpvkneaxnkedjxb', 'qbhpqrwpawefqzfjsa', 'pawefqzfjsanzdukfk', 'bqbhpqrwpawefqzfj', 'dlmyoxbpvkneaxnk', 'xnkedjxbpgsyqovvh']
****************************************************************************************************
ans: bqbhpqrwpawefqzfjsanzdukfkdlmyoxbpvkneaxnkedjxbpgsyqovvhnqjvzryhfjdsxmwolwomeeewvi
****************************************************************************************************
case:
['vgrikrnwezryimj', 'umwgwvzpsfpmctzt', 'pjourlpgeemdjor', 'urlpgeemdjorpzbkbz', 'jorpzbkbzcqyewih', 'xuwkzvoczozhhvf', 'ihbumoogibirbsvch', 'nwezryimjivvpjourlp', 'kzvoczozhhvfwgeplv', 'ezryimjivvpjourlpgee', 'zhhvfwgeplvqngglu', 'rikrnwezryimjivvp']
****************************************************************************************************
ans: xuwkzvoczozhhvfwgeplvqngglumwgwvzpsfpmctztvgrikrnwezryimjivvpjourlpgeemdjorpzbkbzcqyewihbumoogibirbsvch
****************************************************************************************************
case:
['nbsgonqmpreelpbr', 'hnysjajtiguehrokus', 'udgzbzmevnkzzba', 'axtbmcpbmoubyoscn', 'vqnbsgonqmpreel', 'xvqnbsgonqmpree', 'ajtiguehrokustktudgz', 'brgkgihuetpqrhhbhn', 'dgzbzmevnkzzbaxtbmcp', 'ehrokustktudgzbzmevn', 'uetpqrhhbhnysjaj', 'vnkzzbaxtbmcpbmo']
****************************************************************************************************
ans: xvqnbsgonqmpreelpbrgkgihuetpqrhhbhnysjajtiguehrokustktudgzbzmevnkzzbaxtbmcpbmoubyoscn
****************************************************************************************************
case:
['orugbsuuxowmhjh', 'zjyxzmpduthlsioor', 'qtxocgehmhfqnstl', 'tlrlcnnrsyryfrywuebq', 'hozjyxzmpduthlsio', 'hjhdmnqtxocgehm', 'mjhzwdudlnbfkjawqacf', 'hfqnstlrlcnnrsyryfry', 'yfrywuebqhvwewzmq', 'zzieemjhzwdudlnbfkj', 'nnrsyryfrywuebqhvw', 'acfgaihbhozjyxzmpdut']
****************************************************************************************************
ans: zzieemjhzwdudlnbfkjawqacfgaihbhozjyxzmpduthlsioorugbsuuxowmhjhdmnqtxocgehmhfqnstlrlcnnrsyryfrywuebqhvwewzmq
****************************************************************************************************
case:
['phuutlgczfspygaljkv', 'fspygaljkvahvuii', 'csywjodtnkynkjckq', 'poyykqyrhbvcwvjl', 'xijupvzzwphuutlg', 'aljkvahvuiivqbqrw', 'vahvuiivqbqrwryd', 'wjodtnkynkjckqurgu', 'ecdmbshotqbxjqgbou', 'hvuiivqbqrwrydgnr', 'ivqbqrwrydgnrubcsywj', 'wphuutlgczfspyga']
****************************************************************************************************
ans: ecdmbshotqbxjqgbouxijupvzzwphuutlgczfspygaljkvahvuiivqbqrwrydgnrubcsywjodtnkynkjckqurgupoyykqyrhbvcwvjl
也请参见动态编程方法: https://leetcode.com/problems/find-the-shortest-superstring/solution/