2015-06-27 3 views
8

Programmiersprache: Python 3.4Wie optimiert man ein Python-Skript, das 4 ** k mal läuft?

Ich habe ein Programm für den Kurs Bioinformatik 1 von Coursera geschrieben. Das Programm funktioniert in Ordnung, aber ist sehr langsam für große Datensätze. Ich schätze, das liegt daran, dass die Schleife 4 x k mal läuft, wobei k die Länge der Teilzeichenfolge ist, die an die Funktion übergeben wird. Eingabe: Strings Text und Muster zusammen mit einer ganzen Zahl d. Ausgabe: Alle Anfangspositionen, bei denen Muster als Teilzeichenfolge von Text mit höchstens d Mismatches angezeigt wird.

Dies ist mein Code:

def MotifCount(string1, substring, d): 
    k = 4 ** (len(substring)) 
    codeArray = list(itertools.product(['A', 'C', 'G', 'T'], repeat=len(substring))) 
    for i in range(k): 
     codeArray2 = ''.join(list(codeArray[i])) 
     HammingValue = HammingDistance(codeArray2, substring) 
     if HammingValue <= d: 
      for j in range(len(string1)): 
       if(string1.find(codeArray2, j) == j): 
        print(j) 



def HammingDistance(string_1, string_2): 
    length_1 = len(string_1) 
    length_2 = len(string_2) 
    count = 0 
    for i in range(length_1): 
     if string_1[i] != string_2[i]: 
      count += 1 
    return count 

Probe Input:

CGCCCGAATCCAGAACGCATTCCCATATTTCGGGACCACTGGCCTCCACGGTACGGACGTCAATCAAAT 
ATTCTGGA 
3 

Ausgang:

6 7 26 27 

Ich möchte diesen Code für größere Datenmengen optimieren. Gibt es eine Möglichkeit, die Laufzeit des Codes zu reduzieren?

+5

Ihre Lösung sieht wie eine rohe Gewaltmethode aus. Viele Muster exponentiell zu erstellen und dann alle zu überprüfen, kann niemals effizient sein. Ich denke du musst zu einem anderen Algorithmus wechseln. Ich bin mir nicht sicher, was der beste Algorithmus hier ist, aber eine vereinfachte Version einer lokalen Sequenzausrichtung wird wahrscheinlich bereits die Dinge drastisch beschleunigen. – cel

+0

Danke. Ich lerne das Thema jetzt. Ich werde es nachschlagen. :) – DarkRose

Antwort

3
import itertools 

def HammingDistance(string_1, string_2): 
    assert len(string_1) == len(string_2) 
    return sum(c1 != c2 for c1, c2 in zip(string_1, string_2)) 

def MotifCount(string1, substring, d): 
    for i in range(len(string1) - len(substring) + 1): 
     if HammingDistance(string1[i:i+len(substring)], substring) <= d: 
      print(i) 

MotifCount("CGCCCGAATCCAGAACGCATTCCCATATTTCGGGACCACTGGCCTCCACGGTACGGACGTCAATCAAAT", "ATTCTGGA", 3) 

Es gibt:

6 
7 
26 
27 

schnell.

+0

Die Verwendung von 'xrange' anstelle von' range' wird Ihnen auch eine kleine Verbesserung bringen, besonders wenn die Längen groß sind. –

+2

@MartinEvans, dies gilt nur für Python2, die Frage ist über Python3.4. – cel

+0

Ich denke, anstelle von 'range (len (string1) - len (substring))' sollte es 'range (len (string1) - len (substring) +1)', beachten Sie die '+ 1', weil die obere Grenze ist Exklusiv und der letzte Index, den das Muster starten soll, ist 'len (string1) - len (substring)'. – halex

Verwandte Themen