メモリの問題がサフィックスツリーの作成にある場合は、必要がありますか?
word=get_string(4**12)+"$"
def matcher(word, match_string):
positions = [-1]
while 1:
positions.append(word.find(match_string, positions[-1] + 1))
if positions[-1] == -1:
return positions[1:-1]
print matcher(word,'AAAAAAAAAAAA')
[13331731, 13331732, 13331733]
print matcher('AACTATAAATTTACCA','AT')
[4, 8]
私のマシンはかなり古いですが、これは4^12文字列を使用して、実行するために30秒を要した:あなたはこのような単一の文字列にすべての一致を見つけることができます。私は12桁のターゲットを使用したので、いくつかのマッチがあります。また、この解決法は重複した結果を見つけるでしょう。
Hereは、あなたが試みることができる接尾辞木のモジュールで、次のように:Unfortunetly
import suffixtree
stree = suffixtree.SuffixTree(word)
print stree.find_substring("AAAAAAAAAAAA")
、私のマシンは、長い文字列で適切にこれをテストするにはあまりにも遅いです。しかし、おそらくサフィックスツリーが構築されると、検索は非常に高速になるので、大量の検索では適切な呼び出しでなければなりません。さらにfind_substring
は、最初の試合しか返さない(問題があるかどうかわからない、簡単に適応できると確信している)。
更新:あなたは4^12の長さの文字列に千万検索を行う必要がある場合、我々は明らかに9.5年を待つ必要はありませんので、このようにメモリの問題に
を避け、小さい接尾辞木に文字列を分割(標準の簡単な検索、私は最初に、私の遅いマシン上で提案...)。しかし、私たちはサフィックスツリーを使用することができ(したがって、はるかに速くなります)、メモリの問題を回避できます。大きな文字列を管理可能な塊に分割し、チャンクを接尾辞ツリーに変えて1000万回検索し、その塊を破棄して次の塊に移動します。また、各チャンク間のオーバーラップを検索することを忘れないようにする必要があります。私はこれを行うためにいくつかのコードを書いています(大きい文字列が検索されることを前提にして、word
は最大の管理可能な文字列長の倍数で、max_length
です。最後に余りをチェックするようにコードを調整する必要があります。そうでない場合):
def split_find(word,search_words,max_length):
number_sub_trees = len(word)/max_length
matches = {}
for i in xrange(0,number_sub_trees):
stree = suffixtree.SuffixTree(word[max_length*i:max_length*(i+1)])
for search in search_words:
if search not in matches:
match = stree.find_substring(search)
if match > -1:
matches[search] = match + max_length*i,i
if i < number_sub_trees:
match = word[max_length*(i+1) - len(search):max_length*(i+1) + len(search)].find(search)
if match > -1:
matches[search] = match + max_length*i,i
return matches
word=get_string(4**12)
search_words = ['AAAAAAAAAAAAAAAA'] #list of all words to find matches for
max_length = 4**10 #as large as your machine can cope with (multiple of word)
print split_find(word,search_words,max_length)
この例では、最大サフィックスツリーの長さを長さ4^10に制限します。これには約700MBが必要です。 このコードを使用すると、1つの4^12長さの文字列に対して、1,000万回の検索に約13時間かかります(完全一致の検索では一致しているため、検索が速くなります)。しかし、その一環として、約100個の接尾辞ツリーを構築する必要があります.1000 * 41秒= 1時間です。
したがって、実行に要する時間は約14時間で、メモリの問題はありません... 9.5年の大きな改善。 私は1.6GHzのCPUと1GBのRAMを搭載しているので、これ以上の性能を発揮できるはずです。
私はサフィックスツリーに特に慣れていません。あなたの実装は、それが動作する方法についての手がかりを与えません。ライブラリを使用することをお勧めします。 [pytst](http://nicolas.lehuen.com/category/pytst/)。 – MattH
ヒント:ツリー構造にはネストされたdictsが含まれます。 –