Documente Academic
Documente Profesional
Documente Cultură
PROIECT DE LICENTA
COORDONATOR STIINŢIFIC:
Conf. Dr.
Absolvent:
2019
UNIVESITATEA HYPERION din BUCUREŞTI
FACULTATEA de ŞTIINŢE EXACTE ŞI INGINEREŞTI
Specializarea: Informatică
……………….
COORDONATOR STIINŢIFIC:
Conf. Dr. Beteringhe Adrian
Absolvent:
București 2019
TEMA PROIECTULUI
I. Introducere .......................................................................................................................................... 5
2. Alinierea secventelor ........................................................................................................................ 11
2.1 Alinierea în perechi și programarea dinamică ........................................................................ 12
2.2 Alinieri globale vs. alinieri locale .............................................................................................. 19
2.3 Aliniere locală vs. Căutarea in baza de date ............................................................................ 21
2.4 Importanța tabelului de scor ..................................................................................................... 22
3. Alinieri multiple................................................................................................................................ 23
4. Algoritmi utilizați în alinierea secvențială ..................................................................................... 25
4.1 Aliniere Globala (Algoritmul Needleman-Wunsch) ................................................................ 25
4.2 Alinierea locala (Algoritmul Smith & Waterman) .................................................................. 30
4.2.1 Matricile AND ..................................................................................................................... 31
4.2.2 Matricea de proteine ........................................................................................................... 32
5. Limbajul de programare folosit pentru proiectarea aplicației practice ...................................... 38
5.1 Funcționalitatea aplicației ......................................................................................................... 40
6. Concluzii............................................................................................................................................ 44
Bibliografie............................................................................................................................................ 45
Anexe ..................................................................................................................................................... 46
I. Introducere
Acest rezultat surprinzător a oferit cunoștințe mecanice importante pentru biologii care
lucrează asupra modului în care această secvență virală duce la provocarea cancerului. De la
această primă aplicare inițială a computerelor la biologie, domeniul bioinformatic a explodat.
Creșterea bioinformaticii este paralelă cu dezvoltarea tehnologiei de secvențiere a ADN-ului.
În același mod în care dezvoltarea microscopului la sfârșitul anilor 1600 a revoluționat
științele biologice, permițând Anton Van Leeuwenhoek să privească celulele pentru prima
dată, tehnologia de secvențiere a ADN-ului a revoluționat domeniul bioinformatic. Creșterea
rapidă a bioinformaticii poate fi ilustrată prin creșterea secvențelor ADN conținute în
depozitul public al secvențelor de nucleotide numite GenBank.
Viitorul bioinformaticii este integrarea. De exemplu, integrarea unei mari varietăți de surse
de date, cum ar fi datele clinice și genomice, ne va permite să folosim simptomele bolii pentru
a prezice mutațiile genetice și invers. Integrarea datelor GIS, cum ar fi hărțile, sistemele
meteorologice, datele privind sănătatea culturilor și genotipul, ne va permite să anticipăm
rezultatele reușite ale experimentelor în agricultură. O altă arie viitoare de cercetare în
bioinformatică este genomica comparativă pe scară largă. De exemplu, dezvoltarea de
instrumente care pot face comparații pe 10 direcții ale genomului va împinge înainte rata de
descoperire în acest domeniu de bioinformatică. În acest sens, modelarea și vizualizarea
rețelelor complete de sisteme complexe ar putea fi utilizate în viitor pentru a prezice modul în
care sistemul (sau celula) reacționează, de exemplu, la un medicament. Un set tehnic de
provocări se confruntă cu bioinformatica și se adresează prin computere mai rapide, progresele
tehnologice în spațiul de stocare pe disc și creșterea lărgimii de bandă, dar de departe una
dintre cele mai mari obstacole cu care se confruntă bioinformatica astăzi, este numărul mic de
cercetători din domeniu. Acest lucru se schimbă pe măsură ce bioinformatica se îndreaptă spre
prim-planul cercetării, dar acest decalaj în expertiză a dus la lacune reale în cunoașterea
bioinformaticii în comunitatea de cercetare. În cele din urmă, o întrebare cheie de cercetare
pentru viitorul bioinformaticilor va fi cum să comparăm computațional observații biologice
complexe, cum ar fi modele de expresie genetică și rețele de proteine. Bioinformatica este
despre convertirea observațiilor biologice într-un model pe care un calculator îl va înțelege.
Aceasta este o sarcină foarte dificilă, deoarece biologia poate fi foarte complexă. Această
problemă a modului de a digitiza datele fenotipice, cum ar fi comportamentul,
electrocardiogramele și sănătatea culturilor într-o formă citită de calculator, oferă provocări
interesante pentru viitorii bioinformaticieni.
Ce este un algoritm?
Figura 2. Helicaza
Al doilea pas - Helicaza desparte cele două lanțuri organice ale ADN-ului, creând o așa-zisă
furculiță de replicare. Cele două lanțuri sunt complementare și se execută în direcții opuse
(una este denumită 3’ → 5’, cealaltă 5’ → 3’). Două alte mașini moleculare, topoizomeraza și
proteina de legare monocatenară (nereprezentată) se leagă la catene pentru a ajuta la
ameliorarea instabilității ADN-ului.
Figura 3. Topoizomeraza
Al treilea pas - Primerii, care sunt secvențe scurte de ARN, sunt sintetizate de un complex
proteic numit primază și se blochează pe poziții specifice în lanțurile nou deschise, furnizând o
ancoră pentru următoarea etapă. Fără primeri, următorul pas nu poate începe.
Al patrulea pas - O polimerază ADN (încă o altă mașină moleculară) se leagă la fiecare catenă
de ADN șablon proaspăt separat. Polimeraza ADN traversează firele părinte numai în direcția
3 → 5. Prin urmare, polimerazele ADN atașate la cele două fire ADN se mișcă în direcții
opuse.
Figura 5. Polimeraza ADN
Al cincilea pas - La fiecare nucleotidă, polimeraza ADN potrivește nucleotida lanțului șablon
cu baza complementară și o adaugă la lanțul sintetizat. Înainte de a trece la următoarea
nucleotidă, polimeraza ADN verifică pentru a se asigura că baza corectă a fost asociată la
poziția curentă. Dacă nu, elimină baza incorectă și reîncercă. Deoarece polimeraza ADN poate
traversa ADN-ul doar in directia 3 → 5 si din moment ce cele doua fire de ADN ruleaza in
directii opuse, numai o catena a ADN-ului template poate fi folosită de polimeraza pentru a
sintetiza continuu complementul; Cealaltă componentă necesită oprire și repornire ocazională.
Acest lucru are ca rezultat segmente scurte numite fragmente Okazaki.
Pasul al şaselea - O altă mașină moleculară, ligaza ADN, repara gap-urile din noul ADN
sintetizat, care leagă efectiv toate fragmentele Okazaki într-o singură moleculă și curăță orice
rupturi ale firului primar.
Pasul al şaptelea - Când tot ADN-ul a fost copiat într-o astfel de manieră, firele originale se
separă, astfel încât se formează două perechi de fire ADN, fiecare pereche constând dintr-o
catenă veche și una nouă sintetizată.
2. Alinierea secventelor
Având un tabel de scor, se poate compara orice set de aliniamente pentru același set de
secvențe inițiale. Cel care are cel mai bun scor va fi considerat cea mai bună aliniere. De
exemplu, stabilim costul pentru o potrivire +1, costul unei nepotriviri la -3 și costul unui gap
de -4. Figura următoare prezintă două alinieri posibile ale secvențelor ACCTGATCCG și
ACTGATCAG. În prima aliniere posibilă există 8 potriviri (8*(+1) = 8), o nepotrivire
(1*(-3) = -3) și un gap (1*(-4) = -4), ceea ce inseamna un scor total de +1. În cea de-a doua
aliniere posibilă, există 5 potriviri (+5), 4 nepotriviri (-12) și un gap (-4), cu un scor total de
-11. Prima aliniere are un scor mai mare decât cel de-al doilea și ar fi considerat o aliniere mai
bună. Dar cum știm că este cea mai bună posibilă aliniere?
Este imposibil să se evalueze toate alinierile posibile. Luați cazul simplu în care o
secvență de 100 de caractere este aliniată cu o secvență de 95 de caractere. Dacă tot ceea ce
facem este să adăugăm 5 gap-uri la cea de-a doua secvență (pentru a o aduce la 100 de
caractere totale), există aproximativ 55 de milioane de alinieri posibile. Deoarece este posibil
să fie nevoie să adăugăm gap-uri la ambele secvențe, numărul efectiv de aliniamente posibile
este semnificativ mai mare.
Alinierea secvenței în perechi este mai complicată decât calculul secvenței Fibonacci,
însă este implicat același principiu. Scorul de aliniere pentru o pereche de secvențe poate fi
determinat recursiv prin ruperea problemei în combinația de caractere unice la sfârșitul
secvențelor și subsecvențele lor aliniate optim. Dacă secvențele x și y au m și n caractere,
ultima poziție a alinierii lor poate avea trei posibilități: xm și yn sunt aliniate, xm este aliniat
cu un gap cu yn undeva în urmă sau yn este aliniat cu un gap cu xm undeva în urmă. Scorul de
aliniere pentru fiecare caz este scorul pentru poziția finală plus scorul alinierii optime a
secvenței din urmă (fiecare loc este marcat independent, astfel încât scorul segmentelor de
aliniere poate fi adăugat pentru un scor total). Scorul general optim este maximul scorului
pentru cele trei cazuri. Critic, scorul optim pentru fiecare dintre subsecvențele aliniate poate fi
determinat în același mod: trei cazuri posibile pentru poziția finală plus alinierea optimă a
subsecvenței în amonte pentru fiecare caz. Astfel, o formulă pentru scorul de aliniere optimă
poate fi scrisă într-un format simplu recursiv:
𝑆(𝑖 − 1, 𝑗 − 1) + 𝜎(𝑥𝑖 , 𝑦𝑗 )
𝑆(𝑖, 𝑗) = 𝑚𝑎𝑥 { 𝑆(𝑖 − 1, 𝑗) + 𝛾
𝑆(𝑖, 𝑗 − 1) + 𝛾
unde S (i, j) este scorul pentru alinierea optimă de la poziția 1 la i în secvența x și de la 1 până
la j în secvența y, g este costul gap-ului și s (𝑥𝑖 ,𝑦𝑗 ) este scorul de potrivire/nepotrivire pentru
perechi la pozițiile 𝑥𝑖 şi 𝑦𝑗 .
Deși este ușor de scris, această formulă este foarte ineficientă pentru rezolvare și, ca și în cazul
secvenței Fibonacci, duce la o determinare redundantă a punctajului optim pentru alinierile
subsecvențelor care vor apărea din nou și din nou. Soluția de programare dinamică
funcționează pornind de la alinierea optimă a celor mai mici subsecvențe posibile (nimic în
secvență x aliniat la nimic în secvența y) și determinarea progresivă a scorului optim pentru
secvențe mai lungi și mai lungi prin adăugarea de caractere una câte una. Urmărind scorul
optim pentru fiecare subsecvență posibilă aliniată într-o matrice, scorul optim și alinierea
secvențelor complete pot fi ușor și eficient determinate.
În exemplul nostru, prima celulă (A vs G) poate avea trei valori: (1) scorul celulei din
stânga-sus 0, plus costul de nepotrivire (A / G este o nepotrivire), 0 + (-1) = -1; (2) scorul
celulei de deasupra lui, -2, plus scorul decalajului, -2 + (-2) = -4; Sau (3) scorul celulei din
stânga, -2, plus scorul decalajului, -2 + (-2) = -4. Maximul acestora este primul scor, -1, care
este introdus în celulă, împreună cu o săgeată spre stânga sus pentru a ne reaminti că este acea
cale din care a rezultat scorul. Repetăm pentru celula următoare (la dreapta). Valorile posibile
pentru această celulă sunt -2 + -1 = -3, -4 + -2 = -6 sau -1 + -2 = -3. Valoarea maximă este de
-3, dar acest lucru poate fi obținut din două căi separate, așa că înregistrăm ambele căi folosind
săgețile de urmărire.
Această procedură se repetă până când întreaga matrice este completată cu valori.
Valoarea din ultima celulă, din dreapta jos (-5 în exemplul nostru), reprezintă scorul celei mai
bune alinieri (având în vedere funcția de scor). Pentru a găsi această aliniere, începe cu această
celulă și urmează săgețile înapoi în colțul din stânga sus al matricei. În urma unei săgeți
diagonale se indică faptul ca acele caractere reprezentate de acel rând și coloana matricei ar
trebui aliniate. În urma unei săgeți verticale se indică faptul că acel caracterul din secvența
de-a lungul axei verticale (caracterul reprezentat de rândul matricei) trebuie aliniat cu un gap
în secvența reprezentată de axa orizontală. În urma unei săgeți orizontale se indică faptul că
acel caracter din secvența de-a lungul axei orizontale (caracterul reprezentat de coloana
matricei) trebuie aliniat cu un gap în secvența reprezentată de axa verticală.
Dacă există mai multe căi posibile înapoi spre partea superioară a matricei, acest lucru
indică faptul că mai multe aliniere în perechi duc la scorul identic și sunt la fel de optime. În
exemplul nostru, există patru căi posibile, care conduc la patru alinieri posibile ale acestor
secvențe, prezentate în figura următoare:
În acest caz specific, s-ar putea argumenta că primul dintre acestea pare să fie o
aliniere mai bună decât celelalte, însă, bazându-se exclusiv pe tabelul de cost specificat, toate
cele patru aliniamente sunt la fel de bune (fiecare dintre aceste alinieri conține trei potriviri și
patru gap-uri). Schimbarea punctajelor poate schimba rezultatul (vezi mai jos). Foarte puține
programe de aliniere produc mai mult de o aliniere, chiar dacă există mai multe aliniamente la
fel de optime; Algoritmii “sim” ai lui Huang (1990) și Huang și Miller (1991) sunt o excepție
notabilă. Modul în care singura aliniere rezultantă produsă de majoritatea programelor este
aleasă din universul posibil alinierilor optime nu este, de obicei, clar.
Aceasta este cea mai simplă abordare a alinierii succesive a perechilor. Îmbunătățirile
vizibile includ utilizarea unor funcții de notare mai complicate. Nu toate neconcordanțele sunt
în mod necesar egale, iar diferite tipuri de neconcordanțe ar putea da scoruri diferite, în funcție
de proprietățile caracterelor. Pentru secvențele ADN, aceste scoruri diferențiale s-ar putea baza
pe modele standard de evoluție a secvenței. De exemplu, este bine cunoscut faptul că
substituțiile tranzitorii apar mai des decât substituțiile transversale, prin urmare, o nepotrivire
transversală ar putea avea un cost mai mare decât o nepotrivire tranzitorie. Pentru secvențele
de proteine, matricele de substituție derivate empiric sunt de obicei folosite pentru a determina
costurile relative ale diferitelor neconcordanțe. Aceste matrici includ matricile PAM (Dayhoff,
1978), JTT (Jones, 1992) și BLOSUM (Henikoff și Henikoff 1992). Aceste matrici includ, de
obicei, factori biologici estimați, cum ar fi conservarea, frecvența și modelele evolutive ale
aminoacizilor individuali. În principiu, s-ar putea să ne imaginăm că oferim beneficii diferite
diferitelor potriviri (de exemplu, poate că un avantaj mai mare ar trebui să fie aducerea unei
alinieri a unei perechi de resturi de cisteină din cauza constrângerilor extreme și a
constrângerilor structurale ale acestui aminoacid).
O altă îmbunătățire a funcției de notare are de a face cu costurile gap-ului. După cum
este descris mai sus, toate gap-urile sunt tratate ca evenimente identice de poziție. Din punct
de vedere biologic, recunoaștem că evenimentele singulare de inserție-ștergere pot (și de multe
ori fac) să acopere mai multe caractere. Prin urmare, este posibil să nu ne dorim ca acel cost al
gap-ului care acoperă trei spatii să tripleze costul unui gap care acoperă doar un singur spatiu
(un cost liniar). Soluția generală constă în folosirea unui scor de cost pentru deschiderea unui
gap și a unui al doilea punctaj pentru extinderea (prelungirea) unui gol (un cost de afinitate)
(Altschul și Erickson 1986; Gotoh 1982, 1986; Taylor 1984). În acest caz, costul total al gap-
ului este O + nE unde O este costul de deschidere a gap-ului, E este costul prelungirii
diferenței și n este lungimea intervalului (sau lungimea extensiei, în funcție de modul în care
algoritmul este definit). Sunt posibile scheme mult mai complicate de marcare a decalajelor de
lungimi diferite, deși majoritatea programelor moderne de aliniere par să utilizeze o formă de
structură a costurilor afine. Unii algoritmi vor varia, de asemenea, în modul în care tratează
lacunele terminale (adică lacunele care apar la începutul sau la sfârșitul unei secvențe); Unii
algoritmi vor da acest cost redus (chiar zero), deoarece nu se poate deduce că apar între
caracterele observate (acest lucru este uneori cunoscut sub numele de aliniere semi-globală).
În exemplul anterior, utilizarea unui cost de gap afin ar elimina alinierea a treia și a
patra din figura anterioară din setul optim, deoarece acestea au fiecare câte trei goluri
independente (cu lungimea 2, 1 și 1), în timp ce primele două alinieri au doar două goluri (de
lungime 3 și 1). Scăderea costului golurilor terminale ar elimina apoi a doua aliniere, deoarece
unul dintre decalaje este intern pentru caracterele observate, în timp ce alinierea inițială
conține numai goluri terminale. Dincolo de schimbările în modul de aliniere, s-au înregistrat
numeroase îmbunătățiri în eficiența abordării de bază dinamice de programare descrise mai
sus, inclusiv, de exemplu, scăderea cerințelor de memorie (Myers și Miller 1988) și numărul
de etape de calcul (Gotoh 1982).
Procedura descrisă până acum este un algoritm de aliniere globală; Adică presupune că
toate secvențele sunt omoloage și încearcă să alinieze toate caracterele în mod optim în cadrul
secvențelor. Această presupunere poate fi incorectă ca rezultat al rearanjării secvențelor pe
scară largă și al schimbării genomului. Într-un astfel de caz, numai subsecțiunile secvențelor
pot fi omoloage, sau secțiunile omoloage pot fi într-o ordine diferită. De exemplu, o secvență
lungă poate fi comandată ABCDEF (unde fiecare literă reprezintă o secțiune de secvență și nu
un caracter individual). O inversiune de secvență a secțiunii CDE poate schimba secvența
dintr-o altă specie la ABEDCF. Deși fiecare secțiune din prima secvență este omologă cu o
secțiune din secvența a doua, ele nu pot fi aliniate global, din cauza rearanjării. Figura
următoare prezintă aliniamente globale posibile dacă secțiunea C, D sau E este aliniată. În
fiecare caz, celelalte două secțiuni nu pot fi aliniate corect.
Odată ce matricea a fost finalizată, cea de-a doua modificare a algoritmului de aliniere locală
este că, mai degrabă decât pornirea în colțul din dreapta jos al matricei, se folosește celula cu
cea mai mare valoare ca poziție de pornire pentru trace-back. În exemplul nostru, aceasta este
celula direct deasupra coltului jos-dreapta, cu un scor de 3. Diferența finală în această metodă
este aceea că trace-back-ul nu continuă în colțul din stânga sus, ci mai degrabă se termină când
săgețile se termină. Rezultatul acestei proceduri este că numai o porțiune din secvențe poate fi
aliniată; Restul secvențelor sunt lăsate nealiniate. Pentru acest exemplu, alinierea locală este
pur și simplu cea prezentată în figura următoare.
Sunt raportate numai părțile aliniate ale secvențelor. Desigur, ar putea fi găsite
aliniamente locale suplimentare ale secvențelor dacă există mai multe celule cu același punctaj
maxim sau prin alegerea punctelor de plecare submaximale. Ca și în cazul alinierii globale, s-
au înregistrat progrese majore în abordările de aliniere locală; Programele majore de aliniere
locală și algoritmii utilizați astăzi includ DIALIGN (Morgenstern 1999; Morgenstern, Frech et
al. 1998) și CHAOS (Brudno, Chapman și colab., 2003; Brudno și Morgenstern 2002).
O mare parte din lucrul la alinierea locală s-a concentrat pe căutarea în baza de date,
mai degrabă decât pe compararea simplă a secvențelor. S-a recunoscut foarte devreme că
algoritmii ar fi necesari pentru a prelua secvențe dintr-o bază de date cu un model similar cu
cel al unei secvențe de interogare (de exemplu, Korn și colab., 1977). Compararea secvențelor
pentru modele similare necesită, într-o anumită formă, alinierea locală, iar metodele locale de
aliniere formează baza tuturor algoritmilor de căutare în baza de date. Cel mai cunoscut
algoritm de căutare a secvențelor, BLAST (Altschul et al., 1990), conține această expresie în
numele său: Instrumentul de căutare pentru alinierea locală (Basic Local Alignment Search
Tool). Necesitatea muncii majore privind alinierea locală derivă din interesul în căutarea în
baza de date, în special în dezvoltarea familiei de algoritmi BLAST și FASTx (Lipman și
Pearson 1985; Pearson și Lipman 1988).
2.4 Importanța tabelului de scor
Algoritmii descriși mai sus permit căutarea unei populații de alinieri posibile în mod
eficient pentru cele mai optime alinieri, dar este cea mai importantă funcție de cost pentru a
determina cea mai bună aliniere reală. Așa cum s-ar aștepta, schimbarea costului poate
schimba care aliniere este considerată a fi cea mai optimă. Luați, de exemplu, perechea de
secvențe CAGCCTCGCTTAG și AATGCCATTGACGG. Dacă efectuăm alinierea globală și
locală a acestor secvențe folosind parametrii ca înainte (+1 potrivire, -1 nepotrivire, -2 gap),
găsim patru aliniamente globale la fel de optime, prezentate în figura A (singura diferență este
poziția gap-ului din a doua secvență) și o aliniere locală (figura B).
Dacă vom schimba parametrii tabelului nostru de cost, astfel încât beneficiul potrivirii
să fie încă +1, dar costul de nepotrivire este acum -0.3 și costul gap-ului este -1.3, s-ar găsi
aceleași patru aliniamente globale, dar alinierea noastră locală se va schimba la cea indicată în
figura următoare. Seturi diferite de valori de punctaj pot duce la alinierea optimă diferită; Cea
mai bună aliniere nu depinde doar de algoritm (global vs. local), ci de parametrii.
3. Alinieri multiple
Abordarea pentru alinierea mai multor secvențe care în cele din urmă a prins este
cunoscută sub denumirea de aliniere progresivă (Feng and Doolittle 1987, 1990). În alinierea
progresivă, se pornește în general prin construirea tuturor aliniamentelor posibile (pentru n
secvențe, există perechi n*(n-1)/2 ). Aceste alinieri în perechi sunt folosite pentru a estima un
arbore filogenetic utilizând un algoritm bazat pe distanțe, cum ar fi metoda unweighted pair
group method with arithmetic mean (UPGMA) sau îmbinarea vecinilor. Folosind arborele ca
ghid, cele mai asemănătoare secvențe sunt aliniate una cu alta folosind un algoritm de perechi.
Unul adaugă apoi succesiv secvențe la aliniere, câte o secvență, pe baza structurii arborelui
filogenetic. Numeroase programe de aliniere multiple s-au bazat pe o adaptare progresivă de
aliniere a algoritmului Needleman-Wunsch, inclusiv ClustalW (Thompson et al., 1994),
probabil cel mai utilizat program de aliniere multiplă globală.
Spre deosebire de algoritmul pereche, algoritmii de aliniere multiplă sunt mai degrabă
euristice decât soluții exacte; Prin căutarea numai a unui subset al populației de aliniamente,
ele găsesc eficient o aliniere care este aproximativ optimă, dar nu este garantată ca fiind cea
mai optimă aliniere posibilă pentru funcția de cost dată. De exemplu, un dezavantaj general al
abordării de aliniere progresivă este cunoscut ca un algoritm greedy; Orice greșeli care se fac
în etapele timpurii ale procedurii nu pot fi corectate prin pași ulteriori. De exemplu, luați cazul
cu trei secvențe scurte a căror aliniere optimă este prezentată în figura A. Presupunând că
arborele de ghidare indică faptul că ar trebui să începem prin alinierea secvențelor 1 și 2,
există trei alinieri posibile cu același scor (o nepotrivire transversală și un gap), prezentate în
figura B. La adăugarea secvenței 3, poziția gap-ului nu poate fi modificată. Astfel, adăugarea
secvenței 3 ar putea conduce la trei alinieri multiple posibile, prezentate în figura C, dintre
care numai prima este optimă. În prima etapă, numai una dintre cele trei aliniamente poate fi
utilizată pentru următoarea etapă, iar dacă este aleasă greșit, rezultatele finale nu vor fi soluția
cea mai optimă.
Aliniamentele multiple rezultate din fiecare dintre cele trei puncte de pornire din figura B.
Numai una dintre ele este egală cu alinierea optimă reală ilustrată în A.
O valoare în linia i și coloana j în matricea de punctare este scorul de aliniere dintre un prefix
al lui S și un prefix T, adică 𝑆𝑗 și 𝑇𝑖 . Acest lucru va deveni clar mai târziu.
Primul rând și prima coloană a matricei de notare sunt umplute cu i × G (unde i = 0, 1, ..., n),
respectiv j × G (unde j = 0, 1, ..., m). Acestea reprezintă inserarea consecutivă a gap-urilor. De
exemplu, numărul -8 din ultima celulă a primului rând al matricei de notare implică
următoarea aliniere cu patru decalări consecutive în secvența de coloană și un scor de aliniere
de -8:
În mod similar, numărul de -12 din ultima celulă din prima coloană a matricei de notare
implică următoarea aliniere cu șase gap-uri consecutive pe secvența de linie și un scor de
aliniere de -12:
Figura 19. Matricea algoritmului Needleman-Wunsch
Prima celulă în care trebuie să calculăm scorul este cea care corespunde primului
caracter S și T, adică celula cu valoarea 2. Pentru a calcula valoarea pentru celulă, avem
nevoie de valori în alte trei celule, una la stânga, una deasupra ei și una la diagonală stânga-
sus, cu valorile lor de celule desemnate ca L (left), U (up) și, respectiv, UL (up-left). Rețineți
că celula are o valoare de UL egala cu 0, o valoare de U egală cu -2 și o valoare de (L) egală
cu -2. Se calculează următoarele trei valori:
Funcția IF de mai sus ia valoarea lui M dacă cele două nucleotide corespondente se
potrivesc sau MM dacă nu. Maximul acestor trei valori este DIAG, adică 2, care a fost
introdus ca primul element calculat în matricea de punctare. Celula este, de asemenea, umplută
cu o săgeată pe diagonala stânga-sus deoarece DIAG este maximul celor trei valori. Dacă
LEFT (sau UP) ar fi maximul celor trei, am fi pus o săgeată stânga (sau sus) în celula
corespunzătoare din matricea backtrack.
Calculul este de la stânga la dreapta și de sus în jos. Pentru cea de-a doua celulă,
maximul celor trei valori este LEFT (= 0), iar celula corespunzătoare din matricea backtrack
este umplută cu o săgeată îndreptată spre stânga. Continuăm calculul până la celula din
dreapta jos, unde valoarea finală este egală cu 4. Acesta este scorul de aliniere. Puteți observa
că celula corespunzătoare nucleotidului G în secvența liniei și celui de-al doilea G din
secvența coloanei este specială cu două săgeți. Veți găsi că valorile DIAG și UP sunt ambele
egale cu 4 în această celulă. Prin urmare, această celulă va conține si sageata spre UL cat si
spre U. O astfel de celulă presupune existența unor alinieri la fel de optime.
Secvențele aliniate sunt obținute direct din matricea backtrack. Începem din celula din
dreapta jos și urmăm direcția săgeții din celulă. Săgeata UL din celula din dreapta-jos
înseamnă că trebuie să aliniem cele două nucleotide corespunzătoare (T și T) în secvențele
liniei și coloanei. Rețineți că ați fi suprapus cele două nucleotide corespunzătoare, indiferent
dacă acestea sunt aceleași sau diferite, atâta timp cât o săgeată UL este în celulă. O săgeată
orientată spre stânga sau spre sus în celulă înseamnă un gap în secvența coloanelor sau
respectiv în secvența liniei.
Săgeata UL din celula din dreapta-jos ne conduce către celula care conține o săgeată în
sus, adică adăugam un gap "-" peste nucleotidul corespunzător (C) în secvența de coloană.
Această săgeată orientată spre sus ne aduce în celula specială cu două săgeți, una UL și alta în
sus. Aceasta duce la construirea alternativă a alinierii secvenței. Dacă alegem săgeata de sus,
vom plasa un caracter gap peste nucleotida corespunzătoare (G) în secvența coloanei și vom
trece la celula cu o valoare de 6 și o săgeată U. Acest lucru duce în cele din urmă la alinierea
secvențelor din figura următoare A. Alternativ, putem alege să urmărim săgeata UL și să
suprapunem cele două nucleotide (G în ambele secvențe) așa cum se arată în figura următoare
B. Acest lucru duce în cele din urmă la alinierea secvenței alternative în figura B.
Ambele aliniamente din figura anterioară au patru potriviri, două gap-uri și zero
nepotriviri. Deci, scorul de aliniere este 4 ∗ 𝑀 + 2 ∗ 𝐺 + 0 ∗ (𝑀𝑀) = 4, pe care îl cunoaștem
deja după terminarea matricei de punctare, a cărei celulă din dreapta-jos conține scorul de
aliniere.
Când secvențele sunt lungi, ar putea exista multe alinieri la fel de optime și puține
programe de calculator ar încerca să le găsească și să le scoată pe toate. În schimb, este urmată
numai o singură cale, care duce la ieșirea doar a uneia dintre potențialele aliniamente la fel de
optime.
Alinierea 1
Alinierea 2
Tabel de scor 1
Tabelul 1. Tabel de scor 2
Deoarece nu există o metodă obiectivă de a alege schema potrivită de punctare, este important
să rețineți că alinierea secvențelor este o metodă de explorare a datelor în locul unei metode
analitice care va conduce la o singură soluție optimă. Din acest motiv, aproape toate
programele software pentru alinierea secvențelor permit utilizatorului să încerce diferite
scheme de notare și editarea manuală post-aliniere.
Schema de punctare simplă pe care am utilizat-o are trei probleme majore. Mai întâi,
tranzițiile (adică substituțiile între nucleotidele A și G și între C și T) apar în general mai
frecvent decât transversiile (când A sau G sunt înlocuite cu C sau T). Acest lucru sugerează că
nu ar trebui să tratăm diferențele tranzitorii și diferențele transversale cu același scor de
nepotrivire. În schimb, tranzițiile ar trebui penalizate mai puțin decât transversiile. În al doilea
rând, există adesea baze ambigue în introducerea secvențelor, de exemplu, R pentru A sau G și
Y pentru C sau T. O pereche A-R nu este nici o potrivire strictă, nici o nepotrivire strictă, dar
are o probabilitate de 0,5 ca fiind o potrivire și o probabilitate de 0,5 ca fiind o tranziție.
Schema de punctare simplă pe care am utilizat-o nu poate rezolva aceste probleme, ceea ce
necesită utilizarea unei matrici de similitudine.
Schema simplă de notare are, de asemenea, o altă problemă, chiar mai gravă, cauzată de o
pedeapsă constantă. Un biolog se va plânge tare că o metodă de aliniere este greșită dacă
consideră că cele două aliniamente alternative din figurile de mai sus sunt la fel de bune și ar fi
ales alinierea din figura a ca o aliniere mai bună. Cea mai simplă soluție la această problemă
este de a folosi ceea ce se numește o funcție afină pentru lacune.
Un exemplu de matrice de similitudine este " transition bias matrix " (tabelul următor)
utilizat în DAMBE (Xia, 2001; Xia și Xie, 2001) pentru alinierea multiplă cu un arbore stelar.
Un arbore stelar conține un singur nod intern cu toate frunzele conectate la același nod intern.
Semnificația matricei 4 × 4 din partea de sus (valorile boldate din tabelul următor) este ușor de
înțeles. Primele patru valori diagonale de 30 sunt echivalente cu scorul de potrivire, un scor de
nepotrivire care implică o transversie sau o tranziție este -30 sau 0, respectiv, deoarece
tranzițiile apar în general mult mai frecvent decât transversiile și, prin urmare, sunt penalizate
mai puțin. Restul matricei implică coduri ambigue specificate în al doilea tabel, conform
Comitetului pentru Nomenclatură al Uniunii Internaționale de Biochimie (1985).
(tabelele au fost preluate din cursurile Springer “Bioinformatics and the Cell Modern
Computational Approaches in Genomics, Proteomics and Transcriptomics” Chapter 2)
Schema de codare este adesea considerată drept codul IUB sau notația IUB. De exemplu,
R reprezintă fie A, fie G, deci o pereche A-R are o probabilitate de 0,5 să fie o potrivire A-A și
o probabilitate de 0,5 să fie o tranziție A-G. Scorul corespunzător (= 15) este, prin urmare,
undeva între o potrivire perfectă și o tranziție. În contrast, Y reprezintă fie C, fie T / U, iar o
pereche A-Y este întotdeauna o transversie, cu un scor de -30.
Un exemplu frecvent utilizat pentru a ilustra efectul unui aminoacid care este înlocuit
cu un aminoacid diferit este anemia celulelor seceră. Anemia celulară este cauzată de o
înlocuire a unui singur aminoacid în lanțul β al hemoglobinei umane la șase poziții, cu un
reziduu de glutamat înlocuit cu un reziduu de valină. Glutamatul este încărcat negativ și
hidrofil și tinde să rămână pe suprafața proteinei în mediul apos din sânge. În schimb, valina
este un reziduu nepolar și hidrofob și tinde să se micsoreze în mijlocul proteinei. Moleculele
de proteine deformate formează apoi fascicule și distorsionează celula roșie din sânge,
rezultând în forma caracteristică a unei seceră. În general, este adevărat că aminoacizii de
polaritate diferită rar se substituie reciproc (Xia și Li, 1998), în timp ce aminoacizii cu
polaritate similară se pot înlocui destul de des (Xia și Kumar, 2006).
(a fost preluata din cursurile Springer “Bioinformatics and the Cell Modern Computational
Approaches in Genomics, Proteomics and Transcriptomics” Chapter 4)
Figura 26. Aliniamente rezultate ăn alinierile locale și utilizănd diverse categorii de matrici
unde x este lungimea decalajului, iar a și b sunt penalizările deschise și, respectiv, extensiile
de decalaj. Pedeapsa de decalaj crește liniar cu lungimea decalajului. BLAST are setările
implicite cu a = 5 și b = 2, împreună cu scorul de potrivire (M) = 1 și scorul de nepotrivire
(MM) = -3.
Pentru prima celulă, DIAG = 1 din cauza potrivirii celor două nucleotide corespunzătoare,
adică perechile A-A. Valorile UP și LEFT sunt ambele -9. Deci, avem 1 în celulă cu o săgeată
UL. Pentru celula următoare, avem
𝐷𝐼𝐴𝐺 = −7 − 3 = −10
𝑈𝑃 = −9 − 2 = −11
𝐿𝐸𝐹𝑇 = 1 − 5 − 2 = −6
Rețineți că valoarea LEFT pentru această celulă este punctată atât cu gap-ul deschis,
cât și cu penalizarea extinderii spațiului, deoarece celula precedentă (cu valoare = 1) are o
săgeată UL, adică nu există nici un gap. Dacă celula precedentă are o săgeată spre stânga, ceea
ce înseamnă că spațiul a fost deja deschis, s-ar aplica numai pedeapsa de extindere a spațiului.
Cea mai mare valoare a celor trei este LEFT (=-6), iar celula este deci completată cu -6 şi o
sageată stânga. Acest proces continuă până ajungem la ultima celulă, cu o valoare de -5.
Acesta este scorul de aliniere bazat pe schema de notare cu penalizări de decalaj specificate cu
funcția afină.
Există câteva celule care necesită explicații. Prima este celula cu o valoare de -4
corespunzătoare nucleotidei G din secvența de linie și a celei de-a doua nucleotide G din
secvența coloană. Celula are două săgeți, una îndreptată spre U și una orientată în UL. Acest
lucru se datorează faptului că valorile DIAG și UP sunt egale cu -4:
𝐷𝐼𝐴𝐺 = −5 + 1 = −4 (2)
𝑈𝑃 = 3 – (5 + 2) = −4 (3)
Dacă această celulă ar fi ultima celulă, adică, dacă ar fi aliniat secvența parțială a liniei "ACG"
împotriva secvenței coloană parțiale "ACGG", am obține două aliniere optimă alternativă
ambele cu scorul de aliniere de -4:
Cealaltă celulă cu două săgeți este în ultima coloană, al doilea rând de jos în sus. Dacă această
celulă ar fi ultima celulă, adică, dacă ar fi aliniat secvența de linie "ACGT" împotriva
secvenței coloană parțiale "ACGGC", am obține două alinieri optime alternative, ambele cu
scorul de aliniere de - 7 (adică, trei potriviri, o nepotrivire și un gap și o penalizare de
extindere a gap-ului):
Cea mai dificilă celulă se află în penultima coloană și penultima linie, adică cea cu o valoare
UP de -6. Valorile DIAG și LEFT pentru această celulă sunt simple:
𝐷𝐼𝐴𝐺 = −7 – 3 = −10
𝐿𝐸𝐹𝑇 = −9 – 2 = −11
Cu toate acestea, valoarea UP depinde de ce săgeți din celula de mai sus (de exemplu,
celula cu o valoare de -4 și două săgeți) ar trebui să luăm. Dacă luăm săgeata UP (adică, un
gol a fost deja deschis), apoi 𝑈𝑃 = −4 − 2 = −6. Cu toate acestea, dacă luăm săgeata UL
(adică, nici un gol nu a fost deschis încă), atunci 𝑈𝑃 = −4 − (5 + 2) = −11. Ar trebui să
alegem valoarea maximă, adică -6, iar acest lucru constrânge celula anterioară (adică celula cu
o valoare de -4 și două săgeți) pentru a avea o săgeată în sus. Cu alte cuvinte, după ce am
introdus o valoare -6 în celulă, celula de deasupra nu va mai avea două săgeți, ci va avea doar
o săgeată în sus. Din acest motiv, am setat săgeata UL din acea celulă la gri, dar am lăsat
săgeata UP neagră.
Acum, urmând săgețile backtrack, obținem alinierea din figura următoare. Alinierea
are patru potriviri și un gap de lungime 2. Deci scorul de aliniere este 4 ∗ 1 − (5 + 2 ∗ 2) =
−5, ceea ce confirmă faptul că matricea noastră de punctare a fost obținută corect deoarece
valoarea din colț dreapta jos din matricea de punctare este scorul de aliniere).
După rularea executabilului se va deschide o fereastră în care sunt prezentate cele două
aliniamente – alinierea globală și cea locală.
Următorul pas este a utiliza procedura Back-Trace pentru obșinerea scorului optim de aliniere.
Figura 33. Introducea secvențele pentru care se dorește alinierea locală precum și schema de scoring
dorită
Următorul pas este a utiliza procedura Back-Trace pentru obșinerea scorului optim de aliniere.
6. Concluzii
Având în vedere că ştiinţa aveansează foarte repede, iar noile informaţii trebuie
depozitate în baze de date voluminoase, este nevoie ca accesul la aceste date să fie rapid şi
eficient. Aplicaţiile deja existente sunt costisitoare atât din punct de vedere al timpului de
prelucrare, cât şi din punct de vedere finaciar. Pentru a dezvolta aplicaţii cât mai utile şi
eficiente sunt necesare cunoştinţe de programare, dar şi de bioinformatică.
Scopul aplicaţiei este acela de a facilita studiul alinierii secvenţiale fără a fi nevoie de
achiziţionarea de soluţii software scumpe, greu de intuit şi utilizat.
Pentru a putea contribui cu inovaţii în acest domeniu, este absolut necesar ca viitorii
bioinformaticieni să stăpânească bine aceste cunoştiinţe, să poată vizualiza aliniamentele şi să
pună în practică teoria, lucru mult mai uşor de realizat datorită acestei aplicații.
Desigur, pe viitor, această aplicaţie va putea fi îmbunătăţită prin adăugarea de noi
algoritmi de aliniere secvenţială, noi metode de aliniere multiplă şi poate chiar şi elemente de
inteligenţă artificială, cu scopul de a o transforma într-o aplicaţie de instruire a studenţilor.
Bibliografie
1. Needleman SB, Wunsch CD (1970). “A general method applicable to the search for
similarities in the amino acid sequence of two proteins". J Mol Biol 48 (3): 443–453.
2. Lesk AM, Introduction to Bioinformatics (edition 3), Oxford Univ Press, Oxford UK, 2008.
3. Smith TF, Waterman MS (1981). “Identification of Common Molecular Subsequences". J
Mol Biol 147: 195-197.
4. Waterman MS, Smith TF, Beyer WA (1976). “Some biological sequences metrics". Adv
Math 20: 367-387.
5. Wong KC, Computational Biology and Bioinformatics: Gene Regulation, CRC Press, 2016.
6. Mihalaș GI, Tudor A, Paralescu S, Bioinformatică, Ed. Victor Babeș, Timișoara, 2011.
7. Isea R (2015), “The Present-Day Meaning of the Word Bioinformatics“, Global J. Adv.
Res., 2, 70-73.
8. Lee C (2003), “Generating consensus sequences from partial order multiple sequence
alignment graphs”. Bioinformatics 19, 999–1008.
9. Luscombe NM, Greenbaum D, Gerstein M (2001), “What is bioinformatics? An
introduction and overview”. YearBook Med. Inf., 83-100.
10. Hsu PC, Evaritus Nwulia MS, Akira Sawa MHS (2009), “Images in Neuroscience: Using
Bioinformatic Tools”. The American Journal of Psychiatry, 166-168.
11. Warren J. Ewens, Gregory R. Grant, “Statistical Methods in Bioinformatics: An
Introduction”. Penn Center for Bioinformatics Computational Biology and Informatics
Laboratory, University of Pennylvania Philadelphia, PA 19104 USA.
12. Grasso, C. and Lee, C. (2004), “Combining partial order alignment and progressive
multiple sequence alignment increases alignment speed and scalability to very large alignment
problems”. Bioinformatics 20, 1546–1556.
Anexe
Codul sursă
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form3 : Form
{
public Form3()
{
InitializeComponent();
}
public int dimPrSecv, dimSecSecv, nrRow = 1, nrCol = 1, pozTextBoxA = 15,
pozTextBoxB = 200, f = 1, poz1 =0;
public TextBox[] publicTextBox;
public int contor = 3, counter = 0;
public int contorNou = 0;
public int localI = 0, localj = 0;
public void calculMatrice(TextBox[] _arrayPrincipal)
{
TextBox[] MyTextBoxDimA = new TextBox[10000];
MyTextBoxDimA = _arrayPrincipal;
int[] rezultat = new int[4];
int CmpSecv2;
int nrPozCalc = (3 * dimPrSecv + 3);
int discrepanta = 3;
for (CmpSecv2 = (3 * dimPrSecv + 2); CmpSecv2 <= (dimPrSecv * dimSecSecv);
CmpSecv2 = CmpSecv2 + dimPrSecv) // ia toate val secv2
{
discrepanta++;
for (int CmpSecv1 = (dimPrSecv + 4); CmpSecv1 <= (dimPrSecv * dimSecSecv);
CmpSecv1++) // ia toate val secv 1
{
nrPozCalc++;
if (nrPozCalc != discrepanta * dimPrSecv + 1) // conditie pt poz care trb calc
{
if (MyTextBoxDimA[CmpSecv1].Text ==
MyTextBoxDimA[CmpSecv2].Text) // oblic
{
rezultat[0] = Convert.ToInt32(MyTextBoxDimA[(nrPozCalc - dimPrSecv -
1)].Text) + Convert.ToInt32(textBox3.Text); // daca e "="
}
else
{
rezultat[0] = Convert.ToInt32(MyTextBoxDimA[(nrPozCalc - dimPrSecv -
1)].Text) + Convert.ToInt32(textBox4.Text); // daca e "!="
}
rezultat[1] = Convert.ToInt32(MyTextBoxDimA[(nrPozCalc -
dimPrSecv)].Text) + Convert.ToInt32(textBox5.Text); // sus
rezultat[2] = Convert.ToInt32(MyTextBoxDimA[(nrPozCalc - 1)].Text) +
Convert.ToInt32(textBox5.Text); // stanga
rezultat[3] = 0;
MyTextBoxDimA[nrPozCalc].Text = rezultat.Max().ToString();
}
if (CmpSecv1 == 2 * dimPrSecv)
{
nrPozCalc = nrPozCalc + 3;
break;
}
}
}
}
public void splitSecv1si2(TextBox[] _arrayPrincipal, int _nrCol, int _nrRow)
{
TextBox[] MyTextBoxDimA = new TextBox[10000];
int nrCol, nrRow;
nrCol = _nrCol;
nrRow = _nrRow;
MyTextBoxDimA = _arrayPrincipal;
if (nrCol > 3 && nrRow == 2)
{
string localText1 = textBox1.Text;
localText1.ToCharArray();
MyTextBoxDimA[f].Text = localText1[localI].ToString();
localI++;
}
if (nrCol == 2 && nrRow > 3)
{
string localText2 = textBox2.Text;
localText2.ToCharArray();
MyTextBoxDimA[f].Text = localText2[localj].ToString();
localj++;
}
}
public void colorareMatrice()
{
int[] compararNumere = new int[3];
int casutaBlue = 0;
int[] VectNRJos = new int[dimPrSecv - 2];
int[] VectNRsus = new int[dimSecSecv - 3];
int i = 0,cmpvct =0;
for (int M = dimPrSecv * dimSecSecv; M >= (dimPrSecv * dimSecSecv - (dimPrSecv
- 3)); M--)
{
VectNRJos[i] = Convert.ToInt32(publicTextBox[M].Text);
i++;
}
i = 0;
for (int M = dimPrSecv * dimSecSecv - dimPrSecv; M >= (dimPrSecv * 4); M = M -
dimPrSecv)
{
VectNRsus[i] = Convert.ToInt32(publicTextBox[M].Text);
i++;
}
cmpvct = VectNRJos.Max() > VectNRsus.Max() ? VectNRJos.Max() :
VectNRsus.Max();
i = 0;
while(i <= dimPrSecv - 2)
{
if (VectNRJos[i] == cmpvct)
{
poz1 = dimPrSecv * dimSecSecv - i;
break;
}
i++;
}
i = 1;
while(i <= dimSecSecv - 4)
{
if (VectNRsus[i] == cmpvct)
{
poz1 = (dimPrSecv * dimSecSecv) - (dimPrSecv * i);
break;
}
i++;
}
casutaBlue = poz1;
publicTextBox[casutaBlue].BackColor = Color.Aqua;
while (casutaBlue != (dimPrSecv * 2) + 3)
{
try
{
compararNumere[0] = Convert.ToInt32(publicTextBox[casutaBlue -
dimPrSecv].Text);
compararNumere[1] = Convert.ToInt32(publicTextBox[casutaBlue - dimPrSecv -
1].Text);
compararNumere[2] = Convert.ToInt32(publicTextBox[casutaBlue - 1].Text);
int numarMaxim = compararNumere.Max();
if (Convert.ToInt32(publicTextBox[casutaBlue - dimPrSecv - 1].Text) ==
numarMaxim)
{
publicTextBox[casutaBlue - dimPrSecv - 1].BackColor = Color.Aqua;
casutaBlue = casutaBlue - dimPrSecv - 1;
}
else if (Convert.ToInt32(publicTextBox[casutaBlue - dimPrSecv].Text) ==
numarMaxim)
{
publicTextBox[casutaBlue - dimPrSecv].BackColor = Color.Aqua;
casutaBlue = casutaBlue - dimPrSecv;
}
else if (Convert.ToInt32(publicTextBox[casutaBlue - 1].Text) == numarMaxim)
{
publicTextBox[casutaBlue - 1].BackColor = Color.Aqua;
casutaBlue = casutaBlue - 1;
}
}
catch
{
if (casutaBlue > (dimPrSecv * 2) + 3)
{
casutaBlue = casutaBlue - dimPrSecv;
}
}
}
}
private void button1_Click_1(object sender, EventArgs e)
{
TextBox[] MyTextBoxDimA = new TextBox[100000];
dimPrSecv = textBox1.TextLength + 3;
dimSecSecv = textBox2.TextLength + 3;
AutoScroll = true;
WindowState = System.Windows.Forms.FormWindowState.Maximized;
while (dimSecSecv >= nrRow)
{
while (dimPrSecv >= nrCol)
{
MyTextBoxDimA[f] = new TextBox();
MyTextBoxDimA[f].Location = new Point(pozTextBoxA, pozTextBoxB);
// sa scrie coloane
if (nrCol == 2 && nrRow == 1)
{
MyTextBoxDimA[f].Text = "Coloane";
}
// pe linia coloane, numara cate coloane sunt
if (nrCol > 2 && nrRow == 1)
{
int i = 3;
while (i <= dimPrSecv)
{
MyTextBoxDimA[i] = new TextBox();
MyTextBoxDimA[i].Location = new Point(pozTextBoxA, pozTextBoxB);
MyTextBoxDimA[i].Text = (i - 3).ToString();
i++;
}
}
// sa scrie linii
if (nrCol == 1 && nrRow == 2)
{
MyTextBoxDimA[f].Text = "Linii";
}
// sub textul de linii , numara cate linii avem
if (nrCol == 1 && nrRow > 2)
{
int i = dimPrSecv * 2 + 1;
int k = 3;
while (k <= dimSecSecv)
{
MyTextBoxDimA[i] = new TextBox();
MyTextBoxDimA[i].Location = new Point(pozTextBoxA, pozTextBoxB);
MyTextBoxDimA[i].Text = (nrRow - 3).ToString();
k++;
i = i + dimPrSecv;
}
}
// 0 pe coloana
if (nrCol > 2 && nrRow == 3)
{
if (contor <= dimPrSecv)
{
MyTextBoxDimA[f].Text = counter.ToString();
counter = 0;
contor++;
}
}
// 0 pe linie
if (nrCol == 3 && nrRow > 3)
{
MyTextBoxDimA[f].Text = contorNou.ToString();
contorNou = 0;
}
this.splitSecv1si2(MyTextBoxDimA, nrCol, nrRow);
MyTextBoxDimA[f].Size = new Size(50, 10);
MyTextBoxDimA[f].TabIndex = 2;
Controls.Add(MyTextBoxDimA[1]);
Controls.Add(MyTextBoxDimA[f]);
pozTextBoxA = pozTextBoxA + 50;
f++;
nrCol++;
}
pozTextBoxB = pozTextBoxB + 30;
nrCol = 1;
nrRow++;
pozTextBoxA = 15;
}
this.calculMatrice(MyTextBoxDimA);
publicTextBox = MyTextBoxDimA;
}
private void button2_Click_1(object sender, EventArgs e)
{
this.colorareMatrice();
}
private void button3_Click_1(object sender, EventArgs e)
{
int[] compararNumere = new int[3];
int localcount = poz1-(dimPrSecv * (dimSecSecv-2)) -1;
int countsecv2 = 0;
int casutaBlue = poz1;
if (publicTextBox[dimPrSecv * dimSecSecv] != null)
{
textBox6.Text = publicTextBox[dimPrSecv * 2].Text.ToString();
textBox7.Text = publicTextBox[(dimPrSecv * dimSecSecv) - (dimPrSecv -
2)].Text.ToString();
}
while (casutaBlue != (dimPrSecv * 2) + 3)
{
try
{
compararNumere[0] = Convert.ToInt32(publicTextBox[casutaBlue -
dimPrSecv].Text);
compararNumere[1] = Convert.ToInt32(publicTextBox[casutaBlue - dimPrSecv -
1].Text);
compararNumere[2] = Convert.ToInt32(publicTextBox[casutaBlue - 1].Text);
int numarMaxim = compararNumere.Max();
if (Convert.ToInt32(publicTextBox[casutaBlue - dimPrSecv].Text) ==
numarMaxim)
{
countsecv2 = ((dimPrSecv * dimSecSecv) - (casutaBlue - dimPrSecv)) %
dimPrSecv + (casutaBlue - dimPrSecv) - (dimPrSecv - 2);
textBox6.Text = textBox6.Text + "_";
textBox7.Text = textBox7.Text + publicTextBox[countsecv2].Text.ToString();
casutaBlue = casutaBlue - dimPrSecv;
}
else if (Convert.ToInt32(publicTextBox[casutaBlue - dimPrSecv - 1].Text) ==
numarMaxim)
{
countsecv2 = ((dimPrSecv * dimSecSecv) - (casutaBlue - dimPrSecv - 1)) %
dimPrSecv + (casutaBlue - dimPrSecv - 1) - (dimPrSecv - 2);
textBox6.Text = textBox6.Text + publicTextBox[localcount].Text.ToString();
textBox7.Text = textBox7.Text + publicTextBox[countsecv2].Text.ToString();
localcount--;
casutaBlue = casutaBlue - dimPrSecv - 1;
}
else if (Convert.ToInt32(publicTextBox[casutaBlue - 1].Text) == numarMaxim)
{
textBox6.Text = textBox6.Text + publicTextBox[localcount].Text.ToString();
textBox7.Text = textBox7.Text + "_";
localcount--;
casutaBlue = casutaBlue - 1;
}
}
catch
{
if (casutaBlue > (dimPrSecv * 2) + 3)
{
break;
}
}
}
string localText6 = textBox6.Text;
localText6.ToCharArray();
textBox6.Clear();
for (int h = localText6.Length - 2; h >= 0; h--)
{
textBox6.Text = textBox6.Text + localText6[h];
}
string localText7 = textBox7.Text;
localText7.ToCharArray();
textBox7.Clear();
for (int h = localText7.Length - 1; h >= 0; h--)
{
textBox7.Text = textBox7.Text + localText7[h];
}
}
private void button4_Click(object sender, EventArgs e)
{
string charArryTextBox6 = textBox6.Text;
string charArryTextBox7 = textBox7.Text;
int counterG = 0, counterP = 0, counterN = 0;
charArryTextBox6.ToCharArray();
charArryTextBox7.ToCharArray();
for (int i = 0; i <= (charArryTextBox6.Length - 1); i++ )
{
try
{
if (charArryTextBox6[i] == charArryTextBox7[i])
counterP++;
else if (charArryTextBox6[i] != charArryTextBox7[i])
{
if (charArryTextBox6[i] == Convert.ToChar("_") || charArryTextBox7[i] ==
Convert.ToChar("_"))
counterG++;
else
counterN++;
}
}
catch
{
counterG++;
}
}
int scor = (counterP * Convert.ToInt32(textBox3.Text)) + (counterN *
Convert.ToInt32(textBox4.Text)) + (counterG * Convert.ToInt32(textBox5.Text));
textBox8.Text = scor.ToString();
}
}
}