760 likes | 951 Views
Sisteme de programe pentru timp real. Universitatea “Politehnica” din Bucuresti 2005-2006 Adina Magda Florea http://turing.cs.pub.ro/sptr_06. Structura curs. Prelucrarea sirurilor de caractere Criptografie si criptosisteme Retele neurale Algoritmi genetici Retele Bayesiene
E N D
Sisteme de programepentru timp real Universitatea “Politehnica” din Bucuresti 2005-2006 Adina Magda Florea http://turing.cs.pub.ro/sptr_06
Structura curs • Prelucrarea sirurilor de caractere • Criptografie si criptosisteme • Retele neurale • Algoritmi genetici • Retele Bayesiene • Programare web
Informatii curs Pagina Web a cursului http://turing.cs.pub.ro/sptr_06 Notare • Laborator 30% • Tema de casa de semestru 20% • Examen 50% • Minimum 7 prezente la laborator
Curs Nr. 1&2 • Complexitatea calculului • Probleme NP-complete • Prelucrarea sirurilor de caractere
Complexitatea calculului Analiza algoritmilor • o “dimensiune” N • timpul mediu (average case) • timpul cel mai nefavorabil (worst case) • limita a performantei • deducerea timpului mediu • identificarea operatiilor abstracte
Clasificarea algoritmilor Timp de executie proportional cu: • Constant • log N • N • N log N • N2 • N3 • 2N • Timpul de executie a unui program • C1 * f(N) + C2 • Ce inseamna “a fi proportional cu” ?
Complexitatea calculului • studiul cazului cel mai nefavorabil (worst case) ignorind factorii constanti • notatia O mare • DEFINTIE: O functie g(N) se spune a fi O(f(N)) daca exista constantele pozitive C0 si N0 astfel incat g(N) < C0 *f(N) pentru orice N > N0. • limita superioara a performantelor unui algoritm
Complexitatea calculului • O(f(N)) este o limita superioara si, in realitate, poate fi mult mai scazuta; • intrarea ce determina cazul cel mai nefavorabil poate sa nu apara niciodata in practica; • constanta C0 nu se cunoaste si s-ar putea sa nu fie mica; • constanta N0 nu se cunoaste si s-ar putea sa nu fie mica.
Complexitatea calculului • notatia • limita inferioara a performantelor unui algoritm (f1(N) (“big omega”) • DEFINTIE: O functie g(N) se spune a fi (f1(N)) daca exista o constanta pozitiva C0 astfel incit g(N) C0 * f1(N) pentru un numar infinit de mare de valori ale lui N.
Complexitatea calculului pentru algoritmi recursivi • Descompunerea recursiva a problemei in subprobleme • Timpul de executie pentru acesti algoritmi este determinat de dimensiunea si numarul subproblemelor, precum si de costul descompunerii • CN = complexitatea pentru o intrare de dimensiune N
CN N La fiecare apel recursiv se elimina cate un element de intrare: CN = CN-1+1 int sum(int n) { if (n==) return 1; return n+sum(n-1); } • CN N2/2 Un algoritm care necesita parcurgerea intrarii si elimina un element la fiecare apel recursiv: CN = CN-1 + N, pentru N 2, cu C1 = 1 bubble(int a[], int N) /* bubble sort recursiv */
CNlogN Algoritmul injumatateste intrarea la fiecare apel recursiv: CN = CN/2 + 1, pentru N 2, cu C1 = 0(pt deducere N=2n) int binsearch(int a[], int key, int l, int r) • CN 2N Algoritmul imparte intrarea in doua parti la fiecare pas si apoi prelucreaza recursiv fiecare parte (“Divide and conquer”):CN = 2*CN/2 + 1, pentru N 2, cu C1 = 0 rigla(int l, int r, int h /* Desenarea marcajelor pe o rigla */
CN NlogN Algoritm recursiv care isi imparte intrarea in doua parti la fiecare pas, prelucreaza recursiv fiecare parte si face o trecere liniara peste intrare, fie inainte, fie dupa divizarea intrarii (“Divide and conquer”) : CN = 2 * CN/2 + N, pt N 2, cu C1 = 0. quicksort(int a[], int l, int r)
N2/4, N2/8 • N2/4, N2/4 • N logN,N2 • N logN, N logN • N logN, N logN (sp N) • N,N/2 • logN,logN • N,logN • E sau V2 • V+E sau V2 • V+E sau V2 • (E+V) log V – pr. q. • E log E - Kruskal • Insertion sort N • Bubble sort • Quicksort • Heapsort • Mergesort • Sequential search • Binary search • Binary tree search • Shortest path V, E • Depth-first search • Breadth-first search • Min. spanning tree
Probleme NP-complete • “grele” si “usoare” • Problema usoara: “Exista o cale de la x la y cu cost M ? • Problema grea: “Exista o cale de la x la y cu cost M ? • Algoritmi “eficienti” si algoritmi “ineficienti”
Probleme NP-complete • P: multimea tuturor problemelor ce pot fi solutionate prin algoritmi deterministi, in timp polinomial • NP:multimea tuturor problemelor ce pot fi rezolvate prin algoritmi nedeterministi, in timp polinomial • NP =? P
Clasa problemelor NP-complete • Clasa de echivalenta: daca o problema din NP poate fi rezolvata eficient, atunci toate pot fi rezolvate la fel • Se poate demonstra echivalenta problemelor NP-complete din punct de vedere al algoritmilor de rezolvare • Pentru a demonstra ca o problema X din NP este NP-completa este necesar sa se demonstreze ca o problema NP-completa (Y, cunoscuta) poate fi transformata in timp polinomial - redusa polinomial la problema X
Presupunem ca problema ciclului hamiltonian (CH) este NP-completa(Y) si dorim sa vedem daca cea a comis-voiajorului (CV) este NP-completa(X) • Trebuie ca Y sa fie redusa polinomial la X • Instanta a CH => se construieste o instanta a CV: • oraseCV = noduri din grafCH • distante perechi oraseCV = 1 daca exiata arcCH • = 2 daca nu exista arcCH Se cere CV sa gaseasca un ciclu care include toate orasele si are suma ponderilor V, numarul de noduri din graf – acesta trebuie sa corespunda unui ciclu hamiltonian Am demonstrat ca CV este NP-completa
Exemple de probleme NP-complete • Este o expresie booleana data realizabila ? • Dandu-se un graf neorientat, exista un ciclu hamiltonian continut in el (ciclu ce include toate nodurile) ? • Problema comis-voiajorului: Fiind dat un graf cu ponderi intregi pozitive si un intreg K, sa se gaseasca un ciclu care include toate nodurile si a carui suma a ponderilor sa fie K (sau minima). • Exista un K-clique intr-un graf neorientat G?(K-clique – un subgraf complet - orice pereche de puncte din subgraf este legata de un arc - al lui G cu K noduri)
Este un graf neorientat colorabil cu k culori ? (G este k-colorabil daca exista o atribuire de intregi 1, 2, ... k, reprezentand culori, pentru nodurile din G, astfel incat nu exista doua noduri adiacente de aceeasi culoare. Numarul cromatic al lui G este cel mai mic k pentru care G este k-colorabil.) Exista o acoperire de noduri de dimensiune K intr-un graf neorientat ? (G = (V, E), o acoperire de noduri este un subset S V astfel incit fiecare arc din G esteincident intr-un nod din S, card(S) = K.) • Problema izomorfismului subgrafurilor: este un graf neorientat G izomorf cu un subgraf al unui alt graf neorientat G’ ?
Problema Knapsack: Fiind data secventa de intregi S = i1, i2, ... in si un intreg K, exista o subsecventa a lui S a carei sume este exact K ? Pentru o familie de multimi S1, S2, … Sn, exista o acoperire de multimi formata dintr-o sub-familie de multimi disjuncte ? • Problema planificarii taskurilor: Dandu-se un “deadline” si o multime de taskuri de lungimi variabile, ce trebuie executate pe doua procesoare identice, se pot aranja aceste taskui in asa fel incit “deadline”-ulsa fie respectat ?
Cum se poate evita complexitatea? • algoritm polinomial dar suboptimal; rezulta o solutie apropiata de cea mai buna • se foloseste direct algoritmul exponential daca dimensiunea intrarii nu este mare • algoritm exponential cu euristici
Algoritmi de identificare a sirurilor de caractere • Introducere • Algoritmul cautarii directe • Algoritmul Knuth-Morris-Prat • Algoritmul Boyer-Moore • Algoritmul Rabin-Karp • Algoritmul deplaseaza-aduna
1 Introducere • Identificarea (recunoasterea) sabloanelorin siruri de caractere • sir – a, lungime N • sablon – p, lungime M • Fiind dat un sir de lungime N a = a1a2a3...aN, si un sablon de lungime M p = p1p2p3...pM, se cere sa se gaseasca multimea de pozitii { i 1 i N-M+1 a.i.aiai+1…ai+M-1 = p }
Introducere • Prima aparitie / toate aparitiile • Cum difera de cautarea unei chei • Scurt istoric • Algoritmul fortei brute. Are un timp al cazului cel mai nefavorabil proportional cu N*M, dar in multe cazuri practice, timpule mediu este proportional cu N+M. • In 1970, S.A. Cook a demonstrat teoretic, folosind un model de masina abstracta, ca exista un algoritm de identificare a sabloanelor cu timpul cel mai nefavorabil proportional cu N+M. Pornind de la modelul lui Cook, D.E. Knuth, J.H. Morris si V.R. Pratt au construit un astfel de algoritm. • R.S. Boyer si J.S. Moore au descoperit, in 1976, un algoritm chiar mai rapid decit (2) in multe aplicatii, deoarece examineaza in multe cazuri numai o parte din caracterele textului. • In 1980, R.M. Karp si M.O. Rabin au observat ca problema identificarii sabloanelor nu este mult diferita de o problema standard de cautare si au descoperit un algoritm aproape la fel de simplu ca cel al fortei brute, dar care are virtual intotdeauna timpul proportional cu M+N.
2 Algoritmul cautarii directe int cautsablon1(char *p, char *a) { int i = 0, j = 0; /* i este pointerul in text */ int M = strlen(p); /* j este pointerul in sablon*/ int N = strlen(a); do { while ((i < N) && (j<M) && (a[i]==p[j])) {i++;j++;} if (j==M) return i-M; i- = j-1; j = 0; } while (i<N); return i; }
Algoritmul cautarii directe int cautsablon2(char *p, char *a) { int i, j; int M = strlen(p); int N = strlen(a); for (i=0, j=0; j<M && i<N; i++, j++) while (a[i] != p[j]) { i- = j-1; j = 0; } if (j==M) return i-M; else return i; } Se introduce santinela p la sfarsitul lui a
Algoritmul cautarii directe • Proprietate: Algoritmul cautarii directe necesita, in cazul cel mai nefavorabil, un numar de maxim N*M comparatii de caractere. • Timpul de rulare este proportional, pentru cazul cel mai defavorabil, cu M*(N-M+1), si cum M << N obtinem valoarea aproximativa N*M. • Cazul cel mai nefavorabil poate apare, de exemplu, la prelucrarea imaginilor binare. • In multe aplicatii de prelucrare a textelor, bucla interioara se executa rareori si timpul de rulare este proportional cu N+M.
3. Algoritmul Knuth-Morris-Pratt Idee • startul fals al identificarii consta din caractere deja cunoscute • a – sir, i – index in sir, N • p – sablon, j – index in sablon, M • Caz particular: primul caracter din sablon nu mai apare in sablon i sir: 1000001000000 a sablon: 1000000p j nu i = i – j + 1 da – nu se modifica i si j = 0
Caz general sir: 1010100111 a sablon: 10100111 p j=4 • i trebuie decrementat. Cu cat? • Se poate cunoaste aceasta valoare – depinde de caracterul din sablon • Daca nepotrivirea intre sir si sablon apare pe pozitia j in sablon, si • Exista un k [0, j-1] pentru care p[0] ... p[k-1] = p[j-k] ... p[j-1] atunci o posibila identificare intre sir si sablon poate apare incepand cu caracterul din sir a[i-k] si caracterul din sablon p[j-k]. j = 4, k=2 p[0] p[1] = p[j-k] p[j-1], adica p[0] p[1] = p[2] p[3]
Caz general Trebuie cautat k maxim cu aceasta proprietate. • Daca nu exista k cu ac. proprietatea atunci cautarea se reia de la pozitia i si j=0. • Daca exista un astfel de k atunci i = i – k, j = 0. • Se calculeaza valorile unui vector next[M] pt pjp = cu cat trebuie decrementat i la aparitia unei nepotriviri pe pozitia j • next[j] = numarul maxim de caratere nr de la inceputul sablonului care identifica cu ultimele nr caractere din sablon pana la pozitia j-1 = kmax cu proprietatea anterioara
Vectorul next 10100111 next[4] = 2 j = 4 Reluare cautare i = i – next[j], j = 0 Cum se calculeaza next[j]? • Metoda informala, legata de implementare • Metoda formala, bazata pe modelul formal al unui automat finit determinist care recunoaste un sablon intr-un sir, pentru un alfabet dat. • Se gliseaza o copie a primelor j caractere din sablon peste sablon de la stanga la dreapta, incapand cu primul caracter din copie suprapus cu al doilea caracter din sablon • Se opreste glisarea daca: (a) toate caracterele suprapuse (pana la j-1) coincid sau (b) primul caracter al copiei ajunge pe pozitia j.
Vectorul next - exemplu j next[j] sablon si copie sablon 1 0 10100111 0 matches 1 2 0 10100111 0 matches 10 10 3 1 10100111 101 101 1 match 4 2 10100111 1010 1010 2 matches 5 0 10100111 10100 10100 10100 0 matches 10100 6 1 10100111 101001 1 match 7 1 10100111 1010011 1 match 1010011
Vectorul next • Caracterele identice definesc urmatorul loc posibil in care sablonul se poate identifica cu sirul, dupa ce se gaseste o nepotrivire pe pozitia j (caracterul p[j]). • Distanta cu care trebuie sa ne intoarcem in sir este exact next[j], adica numarul de caractere care coincid. • Este convenabil next[0] = -1. Cum facem sa nu ne intoarcem in sir? • a[i] != p[j] se reia de la i – next[j] si j = 0 • Dar primele next[j] caractere incepand de la pozitia i – next[j] din sir = primele next[j] caractere din sablon i nemodificat si j = next[j]
Exemplu i = 4 ar trebui i = 2 si j = 0 sir: 1010100111 a sablon: 10100111 p j=4 next[4] = 2 acelasi efect daca i nemodificat si j = 2
Algoritmul Knuth-Morris-Pratt int cautKMP(char *p, char *a) { int i, j; int M=strlen(p); int N=strlen(a); initnext(p); for (i=0, j=0; j<M && i<N; i++, j++) while ((j>=0) && (a[i] != p[j])) j = next[j]; if (j==M) return i-M; else return i; } Obs: Pt. j = 0 si a[i] != p[0] este necesar ca i+, j = 0 deci next[0] = -1
Calculul vectorului next void initnext(char *p) { int i,j, M=strlen(p); next[0] = -1; for (i=0, j=-1; i<M; i++, j++, next[i]=j) while ((j>=0) && (p[i] != p[j])) j=next[j]; } Obs: • Dupa incrementarile i++ si j++ avem p[i-j] … p[i-1] = p[0]…p[j-1] • Identificarea efectueaza maxim M+N comparatii de caractere
Algoritm pentru sablon fix Caracterele din sirul de intrare total diferite de cele din sablon sunt citite numai in s0, pe tranzitia s0 p s0, p p0. Automatul citeste un nou caracter de intrare numai pentru tranzitiile “la dreapta”, i.e., daca caracterul din sir se potriveste cu sablonul. Altfel automatul se intoarce fara a citi un nou caracter (acesta este motivul pentru care nu sunt etichetate si tranzitiile “la stinga”).
Algoritm pentru sablon fix int cautKMP1(char *a) { int i=-1; sm: i++; s0: if (a[i]!=‘1’) goto sm; i++; s1: if (a[i]!=‘0’) goto s0; i++; s2: if (a[i]!=‘1’) goto s0; i++; s3: if (a[i]!=‘0’) goto s1; i++; s4: if (a[i]!=‘0’) goto s2; i++; s5: if (a[i]!=‘1’) goto s0; i++; s6: if (a[i]!=‘1’) goto s1; i++; s7: if (a[i]!=‘1’) goto s1; i++; return i-8; }
Caracteristici KMP • Algoritmul KMP presupune precompilarea sablonului, ceea ce este justificat daca M « N, adica textul este considerabil mai lung decat sablonul; • Algoritmul KMP nu decrementeaza indexul din sir, proprietate folositoare mai ales pentru cautarile pe suport extern; • Algoritmul KMP da rezultate bune daca o nepotrivire a aparut dupa o identificare partiala de o anumita lungime. In cazul in care aceste situatii sunt o exceptie, algoritmul nu aduce imbunatatiri semnificative; • Algoritmul KMP imbunatateste timpul cazului cel mai nefavorabil, dar nu si timpul mediu.
4 Algoritmul Boyer-Moore UN EXEMPLU DECAUTARE RAPIDA UTARE UTARE UTARE UTARE UTARE • Potrivit daca intoarcerea in text nu este dificila
Algoritmul Boyer-Moore • Vectorul skip – se defineste pentru fiecare caracter din alfabet • arata, pentru fiecare caracter din alfabet, cat de mult se sare (se deplaseaza sablonul la dreapta) in sir daca acest caracter a provocat nepotrivirea • rutina initskip – initializeaza skip: • skip[index(p[j])] = M-j-1, j=0,M-1 pentru caracterele din sablon • skip[index(c)] = M pentru restul de caractere din alfabet
Algoritmul Boyer-Moore int caut_BM(char *p, char*a) { int i, j, t; int M=strlen(p), N = strlen(a); initskip(p); for (i=M-1, j=M-1; j>=0; i--, j--) while (a[i]!=p[j]) { t = skip[index(a[i])]; i+ = (M-j > t) ? M-j : t; if (i >= N) return N; j = M-1; return i+1; }
Algoritmul Boyer-Moore • Combinarea a doua metode pentru a afla exact cu cat trebuie deplasat la dreapta sirul: metoda prezentata si metoda vectorului next din algoritmul Knuth-Morris-Prat, in varianta de la dreapta la stinga, pentru ca apoi sa se aleaga in skip cea mai mare valoare. • In conditiile acestei modificari, este valabila urmatoarea proprietate. • Proprietate: Algoritmul Boyer-Moore face cel mult M+N comparatii de caractere si foloseste N/M pasi, daca alfabetul nu este mic si sablonul este scurt.
5. Algoritmul Rabin-Karp Idee • Considera textul ca fiind o memorie mare si trateaza fiecare secventa de M caractere a textului ca o cheie intr-o tabela de dispersie (hash). • Trebuie sa calculam functia de dispersie pentru toate secventele posibile de M caractere consecutive din text si sa verificam daca valorile obtinute sunt egale cu functia de dispersie a sablonului. • Artificiu pt. a nu tine toata tabela de dispersie in memorie.
Calculul functiei hash • h(k)=k mod q, unde k este numarul de caractere din sir, iar q (dimensiunea tabelei) este un numar prim mare. • q poate fi chiar foarte mare deoarece tabela hash nu se tine in memorie • Functia de dispersie pentru pozitia i din text se calculeaza pe baza valorii acestei functii pentru pozitia i-1 • Se transforma grupuri de M caractere in numere, prin impachetare ca reprezentare intr-o anumita baza • Aceasta corespund la a scrie caracterele ca numere in baza d, unde d este numarul de caractere posibile din alfabet.
Calculul functie hash • O secventa de M caractere consecutive a[i]…a[i+M-1] corespunde: y = a[i]*dM-1 + a[i-1]*dM-2 + … + a[i+M-1] • Presupunem ca stim valoarea lui h(y) = y mod q. • Deplasarea in text cu o pozitie la dreapta corespunde inlocuirii lui y cu y1 = (y - a[i]*dM-1)*d + a[i+M] • Consideram d=32 (sau orice multiplu de 2 corespunzator) • Cum facem sa nu memoram valorile functiei hash pentru toate grupurile de M caractere din sir?
Calculul functiei hash pt. y1 pe baza lui y Se cunoaste ca: (a + b) mod q = (a mod q + b mod q) mod q (a * b) mod q = (a * (b mod q)) mod q Se doreste sa se arate ca: (a0 *x + a1) mod q = ((a0 mod q) * x + a1) mod q Demonstratie: (a0 * x + a1) mod q = ((a0 * x) mod q + a1 mod q) mod q = = [(x(a0 mod q)) mod q + a1 mod q] mod q = ((a0 mod q) x + a1) mod q Noul sir impachetat y1 se obtine din y astfel (slide precedent): y1 = (y - a[i] * dM-1) * d + a[i+M] Cum se calculeaza y1 mod q pe baza lui y : y1mod q = ((y – a[i] * dM-1) * d + a[i+M]) mod q = ( (y – a[i] * dM-1) mod q * d + a[i+m])mod q
Algoritmul Rabin-Karp int caut_RK(char *p, char *a) { int i; long int dM=1, h1=0, h2=0; int M=strlen(p), N=strlen(a); for (i=1; i<M; i++) dM = (d*dM) % q; // calculeaza d**(M-1) mod q in dM for (i=0; i<M; i++) {h1 = (h1*d + index(p[i]))%q; // functia hash pt sablon h2 = (h2*d + index(a[i]))%q; // functia hash pt text } for (i=0; h1!=h2; i++) {h2 = (h2 + d*q - index(a[i])*dM)%q; // d*q se adauga pt a mentine expresia >0 h2 = (h2 * d + index(a[i+M]))%q; if (i > (N-M)) return N; } return i; }
Caracteristici RK • Algoritmul Rabin-Karp are destul de probabil o complexitate timp liniara. • Algoritmul are timpul proportional cu N+M, dar el gaseste doua siruri cu valori de dispersie egale. • In aceste conditii, trebuie sa comparam sablonul cu cele M caractere din sir, pentru cazul coliziunilor. • Deci, din punct de vedere teoretic, acest algoritm ar putea sa fie tot O(NM), in cazul cel mai defavorabil, in care toate sabloanele gasite ar fi coliziuni putin probabil, deoarece q este mare; in practica, algoritmul foloseste N+M pasi. • Daca sablonul se cauta de mai multe ori, el poate fi considerat o cheie, iar textul poate fi organizat in stucturi eficiente de cautare, cum ar fi arbori binari, tabele de dispersie, etc.