Bartosz Rybicki 71358
Transkrypt
Bartosz Rybicki 71358
Bartosz Rybicki 71358 Marcin Zgórecki 71396 Zastosowanie informatyki w biologii obliczeniowej. Temat: Lokalne dopasowanie wielu sekwencji 1 1. Cel zadania. Zadanie polegało na zaprojektowaniu oraz implementacji algorytmu wyszukującego najlepsze lokalne dopasowanie wielu sekwencji nukleotydowych. Na wejście programu należy dostarczyć zbiór sekwencji, dla których algorytm ma znaleźć najlepsze dopasowanie. Program na wyjściu zwraca ciąg reprezentujący najlepsze dopasowanie wszystkich sekwencji. Funkcja determinująca o jakości danego dopasowania działa w następujący sposób – za zgodność pary dopasowanych nukleotydów +1, za niezgodność -1, za wprowadzoną spację -1. Nasze rozwiązanie w fazie porównywania par sekwencji bazowało na algorytmie SmithaWatermana, będącym algorytmem programowania dynamicznego. Jego złożoność wynosi O(n2) dla sekwencji o długości n – operuje on na dwuwymiarowej macierzy o rozmiarze n × n . Algorytm ten można również zastosować dla porównania wieloelementowego zbioru sekwencji, jednak wtedy jego złożoność drastycznie wzrasta – dla m elementowego zbioru sekwencji o długości n, algorytm bazuje na macierzy o m wymiarach, a złożoność wynosi O(nm). Jest to oczywiście mało efektywne rozwiązanie, zatem na potrzeby projektu przygotowaliśmy własne rozwiązanie odpowiednio zoptymalizowane. 2. Zastosowany algorytm. W pierwszej fazie algorytm szuka najlepszych lokalnych dopasowań dla wszystkich par sekwencji wejściowych. Należy dokonać n2 − n porównań. Wynik opisanej fazy algorytmu 2 przechowywany jest w odpowiedniej macierzy. Również odpowiednie dopasowania są zachowywane do dalszych celów. W celu porównania par sekwencji wykorzystywany jest algorytm Smitha-Watermana. Drugi etap polega na dynamicznej budowie drzewa dopasowan kolejnych sekwencji. Algorytm bazuje przy tym na macierzy utworzonej w etapie pierwszym. Drzewo buduje się porównując ze sobą łancuchy, lub poddrzewa utworzone wcześniej o największym stopniu 2 podobieństwa – zgodnie z wynikiem funkcji oceniającej jakość dopasowań. W przypadku porównywania pojedynczych sekwencji, brany jest pod uwagę wynik umieszczony w macierzy utworzonej w fazie pierwszej. Natomiast, gdy porównywane są poddrzewa powstałe w wyniku wcześniejszego porównania pojedynczych sekwencji, należy zwrócić uwagę, na wybór takiego dopasowania, które posiada mniejszą liczbę spacji. Dopasowania z pierwszej fazy działania algorytmu są przechowywane w odpowiedniej strukturze, zatem nie trzeba ich ponownie szukać. Po operacji wyboru dokonuje się porównanie dwóch interesujących elementów i umieszczenie wyniku we wspomnianej drzewiastej strukturze, łącząc przy tym poddrzewa będące jego składowymi. Przykładowo, jeśli chcemy znaleźć lokalne dopasowanie trzech sekwencji : AACGTCGT AAGTGT ACGTCGT Pierwszym krokiem będzie znalezienie dopasowa dla wszystkich par sekwencji: 3 Na podstawie tych operacji budowana jest macierz : AACGTCGT AACGTCGT AAGTGT ACGTCGT - 4 7 - 3 AAGTGT ACGTCGT - Dodatkowo wyniki dopasowań są zachowywane do późniejszego wykorzystania. Kolejnym krokiem jest budowa drzewa. W pierwszej kolejności brane są pod uwagę sekwencje o największym stopniu podobieństwa. Na tym etapie zastosowano szereg optymalizacji. Algorytm został zaimplementowany w języku C++, który znany jest ze bardzo wydajnych metod zarządzania pamięcią. Skorzystaliśmy z bardzo wydajnych struktur dostępnych w bibliotece STL, takich jak np. Vector czy List. Ich wydajność znacznie przewyższa własne rozwiązania implementowane od podstaw. Do budowy drzewa wykorzystaliśmy szereg własnych struktur opartych na wskaźnikach znanych z C, drzewo budowane jest poprzez dołączanie do istniejącego już poddrzewa kolejnych elementów, przez co w miare iteracji jest ono budowane aż do „korzenia”. Przy operacjach na wskaźnikach pamiętaliśmy o zwalnianiu pamięci, gdy nie będzie już potrzebna, przez co program nie posiada „wycieków pamięci”. 4 3. Testy Do celów testowania wydajności algorytmu przewidziano możliwość generacji kilku rodzajów danych wejściowych. W tym celu przygotowano odpowiedni generator zapewniający zestaw sekwencji spełniających odpowiednio zdefiniowane warunki.Są to odpowiednio : 5 • zbiór losowo wybranych, różniących się od siebie sekwencji o stałej długości, • zbiór identycznych sekwencji, • zbiór losowo wybranych, różniących się wzajemnie sekwencji o zmiennej długości, • zbiór sekwencji nieznacznie różniących się od siebie (o 10% lub 30%) 3.1. Dane losowe o jednakowej długości Dla zbioru sekwencji o stałej predefiniowanej długości oraz losowej budowie wyniki przedstawiają się następująco : 6 3.2. Dane identyczne 7 3.3. Dane losowe o różnej długości. Długość waha się o ±33% od zadeklarowanej w generatorze instancji wartości. 8 3.4. Dane zmienione w 10% 3.5. Dane zmienione w 30% 9 Widać, iż algorytm działa nieco szybciej dla zestawu identycznych sekwencji nukleotydowych, niż dla zestawu różnych sekwencji. Można również zauważyć, iż nieco lepiej algorytm sprawuje się przy zestawie sekwencji różniących się wzajemnie o ok. 10%, niż w przypadku sekwencji różniących się o ok. 30%. Testy przeprowadzono na komputerze wyposażonym w dwurdzeniowy procesor Pentium 4 3GHz, 1024MB pamięci operacyjnej, działającym pod kontrolą systemu Suse Linux. 4. Wnioski • Algorytm działa w czasie wielomianowym – potwierdzają to wykresy. Średnia złożoność będzie wynosić O(m2nlog(n)), gdzie m to ilość badanych sekwencji, natomiast n to ich długość. W pesymistycznym przypadku złożoność wyniesie O(m2n2). Różnica ta wynika z zastosowania w algorytmie struktury drzewiastej. • Wadą proponowanego rozwiązania jest jego duża złożoność pamięciowa wynosząca n2m. • Dla większych instancji problemu algorytm nie będzie wydajny – w takich przypadkach należałoby użyć bardziej wysublimowanych heurystyk, np. z wykorzystaniem algorytmu genetycznego. 10