1 / 15

Programmazione dinamica: problema della sottosequenza più lunga

Programmazione dinamica: problema della sottosequenza più lunga. Esempio problema Algoritmo di ricerca esaustiva Caratterizzazione soluzione ottima Algoritmo ricorsivo Stategia Bottom-up Costruzione soluzione ottima. Problema della sottosequenza più lunga.

urit
Download Presentation

Programmazione dinamica: problema della sottosequenza più lunga

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Programmazione dinamica:problema della sottosequenza più lunga Esempio problema Algoritmo di ricerca esaustiva Caratterizzazione soluzione ottima Algoritmo ricorsivo Stategia Bottom-up Costruzione soluzione ottima

  2. Problema della sottosequenza più lunga Input: vengono dati in ingresso due sequenze x[1…m] e y[1…n] Problema: Cercare una sottosequenza più lunga che sia comune ad entrambe le sequenze. (Longest Common Subsequence, LCS) Verso sequenza x: A B C B D A B BCBA= LCS(x,y) y: B D C A B A Sottosequenza: una sottosequenza di una sequenza Z è un sottoinsieme strettamente crescente di Z

  3. Algoritmo di bruta forza Idea: per ogni sottosequenza di x[1…m] si controlla se è una sottosequenza di y[1…n]. Si memorizza la prima sottosequenza comune più lunga trovata. • Analisi complessità: • Ci vuole tempo O(n) per controllare se una sequenza è sottosequenza di y[1…n] • 2m sottosequenze a partire da x[1…m] (basta pensare ad un vettore binario lungo m, ogni 1 vuol dire che l’elemento appartiene alla sottosequenza) • Caso Peggiore: O(n 2m )→ tempo esponenziale

  4. Soluzione in programmazione dinamica • Lo sviluppo di un algoritmo in programmazione dinamica può essere diviso in quattro fasi o passi: • Caratterizzazione della struttura di una soluzione ottima. • Definizione ricorsiva del valore di una soluzione ottima. • Calcolo del valore di una soluzione ottima con una strategia bottom-up. • Costruzione di una soluzione ottima a partire dalle informazioni calcolate.

  5. Caratterizzazione soluzione ottima • Siano X[1…m] e Y[1…n] due sequenze e sia Z[z1, z2…zk] una LCS (sottosequenza più lunga), allora: • Se xm = ynallora xm = yn = zk e Z[z1, z2…zk-1] è LCS di X[1…m-1] e Y[1…n-1] • Se xm ≠ ynallora: • se xm ≠ zksi ha che Z[z1, z2…zk] è LCS di X[1…m-1] e Y[1…n] • se yn ≠ zksi ha che Z[z1, z2…zk] è LCS di X[1…m] e Y[1…n-1]

  6. Caratterizzazione soluzione ottima • Dimostrazione: • xm = yn • Allora xm = yn = zk. Se non fosse così e xm = yn ≠ zk, allora si potrebbe estendere Z con xm = yn … assurdo! • Si ha dunque che Z[1…k-1] è sottosequenza lunga k-1 sia di X[1…m-1] sia di Y[1…n-1]. • Z[1…k-1] è anche la LCS di X[1…m-1] e di Y[1…n-1]. • Se non fosse così ci sarebbe Z’[1…t] con t > k-1 LCS di X[1…m-1] e di Y[1…n-1]. Allora Z’ potrebbe essere esteso con xm = yn, formando una sottosequenza comune a X[1…m] e Y[1…n] lunga t+1 > k … assurdo!

  7. Caratterizzazione soluzione ottima Dimostrazione: 2. a. xm ≠ zk Z[1…k-1] è anche la LCS di X[1…m-1] e di Y[1…n]. Se non fosse così ci sarebbe Z’[1…t] con t > k LCS di X[1…m-1] e di Y[1…n]. Allora Z’ sarebbe una sottosequenza comune a X[1…m] e Y[1…n] lunga t > k … assurdo! 2. b. yn ≠ zk(speculare)

  8. Definizione ricorsiva soluzione ottima • Siano X[1…i] e Y[1…j] due sequenze e sia Z[z1, z2…zk] una LCS (sottosequenza più lunga), allora: • Se xi = yj allora xi = yj = zk e Z[z1, z2…zk-1] è LCS di X[1…i-1] e Y[1…j-1] • Se xi ≠ yj allora: • se xi ≠ zk si ha che Z[z1, z2…zk] è LCS di X[1…i-1] e Y[1…j] • se yj ≠ zk si ha che Z[z1, z2…zk] è LCS di X[1…i] e Y[1…j-1]

  9. Definizione ricorsiva soluzione ottima Siano X[1…i] e Y[1…j] due sequenze e sia Z[z1, z2…zk] una LCS (sottosequenza più lunga) con lunghezza c[i,j], allora: X: 1 m i 1 j n Y:

  10. Algoritmo ricorsivo Siano X[1…i] e Y[1…j] due sequenze e sia Z[z1, z2…zk] una LCS (sottosequenza più lunga) con lunghezza c[i,j], allora: LCS(X,Y,i,j) • if i =0 and j= 0 • return 0 • if xi =yj • thenreturn LCS(X,Y,i-1,j-1)+1 • else return max(LCS(X,Y,i-1,j) , LCS(X,Y,i,j-1)) Attenzione: Nel caso xi≠yj vengono generate due chiamate ricorsive (LCS(X,Y,i-1,j) e LCS(X,Y,i,j-1)) che possono generare sottoproblemi comuni.

  11. Algoritmo ricorsivo m = 3 n = 4 3,4 3,3 2,4 UGUALI ! Altezza m+n 1,4 2,3 2,3 3,2 1,3 2,2 1,3 2,2 Caso peggiore: xi≠yj sempre. Vengono generate due chiamate ricorsive (LCS(X,Y,i-1,j) e LCS(X,Y,i,j-1)) che possono generare sottoproblemi comuni.

  12. Stategia bottom-up LCS(X,Y) • m ← length[X] • n ← length[Y] • fori ← 1 to m • do c[i,0] ← 0 • forj ← 1 to n • do c[j,0] ← 0 • fori ← 1 to m • doforj ← 1 to n • doif xi =yj • then c[i,j] ← c[i-1,j-1] +1 • b[I,j] ← ‘diag’ • else if c[i-1,j] ≥ c[i, j-1] • thenc[i,j] ← c[i-1,j] • b[I,j] ← ‘up’ • elsec[i,j] ← c[i,j-1] • b[I,j] ← ‘left’

  13. Stategia bottom-up A B C B D A B Tempo = Θ(m n) Spazio = Θ(m n) = numero di sottosequenze per cui calcolare c[i,j] e b[i,j] B D C A B A

  14. Costruzione di una soluzione ottima A B C B D A B b[i,j] serve per ricavare andando a ritroso la LCS trovata. Ogni “diag” corrisponde ad un elemento della LCS. LCS = “BCBA” B D C A B A

  15. Costruzione di una soluzione ottima PRINT-LCS(b,X,Y,i,j) • ifi = 0 or j = 0 • then return • if b[i,j] = “diag” • thenPRINT-LCS(b,X,Y,i-1,j-1) • print “xi” • elseif b[i,j] = “up” • thenPRINT-LCS(b,X,Y,i-1,j) • elsePRINT-LCS(b,X,Y,i,j-1) Il tempo di esecuzione corrisponde a O(m+n), poiché al peggio deve ogni volta decrementare solo uno dei due valori (i oppure j).

More Related