Se i problemi di memoria si trovano nella creazione dell'albero del suffisso, sei sicuro di averne bisogno? Si potrebbe trovare tutte le partite in una singola stringa come questa:
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]
La mia macchina è piuttosto vecchio, e questo ci sono voluti 30 secondi per l'esecuzione, con 4^12 corde. Ho usato un bersaglio a 12 cifre, quindi ci sarebbero state alcune partite. Anche questa soluzione troverà risultati sovrapposti, se ce ne sono.
Here è un modulo albero suffisso si potrebbe provare, in questo modo:
import suffixtree
stree = suffixtree.SuffixTree(word)
print stree.find_substring("AAAAAAAAAAAA")
Unfortunetly, la mia macchina è troppo lento per testare il tutto correttamente con stringhe lunghe. Ma presumibilmente una volta che il suffixtree è stato creato, le ricerche saranno molto veloci, quindi per grandi quantità di ricerche dovrebbe essere una buona chiamata. Inoltre find_substring
restituisce solo la prima corrispondenza (non so se questo è un problema, sono sicuro che potresti adattarlo facilmente).
Aggiornamento: dividere la stringa in alberi di suffisso più piccoli, evitando così problemi di memoria
Quindi se avete bisogno di fare 10 milioni di ricerche su 4^12 stringa di lunghezza, abbiamo chiaramente non vuole aspettare per 9,5 anni (semplice ricerca standard, prima ho suggerito, sulla mia macchina lenta ...). Tuttavia, possiamo ancora usare gli alberi di suffisso (quindi essere molto più veloci), ed evitare i problemi di memoria. Dividi la grande stringa in blocchi gestibili (che sappiamo che la memoria della macchina può farcela) e trasforma un pezzo in un albero di suffisso, cercalo 10 milioni di volte, poi scarta quel pezzo e passa a quello successivo. Dobbiamo anche ricordare di cercare la sovrapposizione tra ogni blocco.Ho scritto qualche codice per fare questo (Assume la grande stringa da cercare, word
è un multiplo della nostra lunghezza massima della stringa gestibile, max_length
, dovrete modificare il codice per controllare anche il resto, alla fine, se questo è non è il caso):
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)
In questo esempio limita la massima lunghezza albero suffisso lunghezza 4^10, che necessita di circa 700 MB. Utilizzando questo codice, per una stringa di lunghezza 4^12, 10 milioni di ricerche dovrebbero richiedere circa 13 ore (ricerche complete, con corrispondenze zero, quindi se ci sono corrispondenze sarà più veloce). Tuttavia, come parte di questo, abbiamo bisogno di costruire 100 suffissi, che richiederanno circa. 00 * 41 secondi = 1 ora.
Quindi il tempo totale per l'esecuzione è di circa 14 ore, senza problemi di memoria ... grande miglioramento su 9,5 anni. Nota che lo sto usando su una CPU da 1.6GHz con 1GB di RAM, quindi dovresti essere in grado di fare meglio di così!
Io non sono particolarmente familiarità con alberi suffisso e l'implementazione non mi sta dando indizi su come si suppone di lavorare. Ti suggerirei di utilizzare una libreria, ad es. [Pytst] (http://nicolas.lehuen.com/category/pytst/). – MattH
Suggerimento: una struttura ad albero comporta dend annidati. –