Esercizio - sottosequenza quasi palindroma di lunghezza massima (compito dell'8 luglio 2024, es. 2)
Fonte: compito di Algoritmi per l'Ingegneria, Ing. Informatica UniPD, 8 luglio 2024, seconda parte, esercizio 2 (17 punti).
Testo
Una stringa di interi si dice quasi palindroma se, per ogni , si ha . Data una stringa , il problema della Longest Quasi Palindrome Subsequence (LQPS) consiste nel determinare la massima lunghezza di una sottosequenza quasi palindroma di .
- (a) [7 punti] Si formuli una proprietà di sottostruttura ottima per il problema sullo spazio delle sottostringhe della stringa e se ne provi la correttezza.
- (b) [5 punti] Sulla base della proprietà provata al punto (a), si derivi una ricorrenza sulla lunghezza della LQPS.
- (c) [5 punti] Si scriva lo pseudocodice bottom-up associato al calcolo della ricorrenza sviluppata al punto precedente e se ne valuti la correttezza e la complessità, in funzione del numero di addizioni e sottrazioni tra i caratteri della stringa.
Soluzione
Idea
Una stringa quasi palindroma è una palindroma in cui "uguale" è sostituito da "differisce al più di ": le coppie simmetriche , , ... devono essere vicine. Per esempio lo è: , e il centro è confrontato con sé stesso. È il problema della sottosequenza palindroma più lunga (Allineamento di stringhe e sottosequenza palindroma più lungadue problemi di DP su stringhe con la stessa struttura della LCS. Allineamento ottimo di due stringhe di DNA con matrice di score S e penalità di gap g: C(i,j) = max{C(i-1,j-1) + s(x_i,y_j), C(i-1,j) + g, C(i,j-1) + g}, C(i,0) = i g, C(0,j) = j g; Theta(mn) tempo, spazio Theta(min{m,n}) con un solo vettore se serve solo il costo. Sottosequenza palindroma più lunga (LPS) sullo spazio delle sottostringhe X_(i..j): p(i,j) = 2 + p(i+1,j-1) se x_i = x_j, altrimenti max{p(i+1,j), p(i,j-1)}; scansione per diagonali, n(n-1)/2 confronti.Allineamento di stringhe e sottosequenza palindroma più lunga →) con una relazione di "compatibilità" tra gli estremi più larga dell'uguaglianza. Come per quella, si tolgono i caratteri dai due estremi, quindi lo spazio dei sottoproblemi è quello delle sottostringhe ().
Una stringa di un solo carattere è sempre quasi palindroma, e una di due caratteri lo è se e solo se i due differiscono di al più .
(a) Proprietà di sottostruttura ottima
Proprietà. Per ogni esiste una , LQPS di , tale che:
- se : ;
- se e : ;
- se e : ;
- se e : , e è una LQPS di ;
- altrimenti ( e ): è la più lunga tra una LQPS di e una LQPS di .
(Come nei problemi analoghi, il punto 4 dice che esiste una LQPS con estremi e , non che tutte le LQPS li abbiano: basta per un algoritmo corretto.)
Dimostrazione. I punti 1, 2 e 3 sono banali (una stringa di un carattere è quasi palindroma; una di due caratteri lo è se e solo se la differenza è al più ).
Punto 4. Sia e . Sia una LQPS qualsiasi di , con . Poiché è quasi palindroma, .
- Non possono valere insieme e : altrimenti sarebbe una sottosequenza di (indici e ), quasi palindroma (le coppie interne sono quelle di e la coppia esterna è compatibile) e più lunga di , contro la massimalità. Quindi oppure .
- Se e , si sostituisce l'ultimo carattere di con (indice ); se e , si sostituisce il primo con . La stringa ottenuta ha la stessa lunghezza , è sottosequenza di , e resta quasi palindroma: le coppie interne non cambiano e la coppia esterna è ora , compatibile. Quindi è una LQPS con e (se e non occorre sostituire nulla).
- è quasi palindroma ed è sottosequenza di . Se non ne fosse una LQPS, sostituendola con una LQPS di (cut-and-paste) si otterrebbe , quasi palindroma e più lunga di : contraddizione.
Punto 5. Sia una LQPS qualsiasi di con e . Se usasse entrambi gli indici e come primo e ultimo elemento (con ), la coppia esterna violerebbe la condizione. Quindi oppure (se vale oppure perché ). Nel primo caso è una sottosequenza quasi palindroma di , nel secondo di ; in entrambi deve essere la migliore, altrimenti con il cut-and-paste se ne troverebbe una più lunga anche in . Poiché le LQPS delle due sottostringhe sono anche sottosequenze quasi palindrome di , è la più lunga delle due.
(b) Ricorrenza
Sia la lunghezza di una LQPS di , per . Dalla proprietà:
La risposta è .
(c) Algoritmo bottom-up
La cella dipende da , e , relative a sottostringhe più corte (di lunghezza , , se ): una scansione per diagonali di lunghezza crescente nel triangolo superiore della tabella è coerente. (Anche "righe dalla alla " e "colonne con righe decrescenti" lo sono.)
LQPS(X)
n <- |X| { X = <x_1, ..., x_n> }
for i <- 1 to n-1 do
L[i, i] <- 1
if |x_i - x_{i+1}| <= 1 then L[i, i+1] <- 2
else L[i, i+1] <- 1
L[n, n] <- 1 { casi base: diagonali l = 1 e l = 2 }
for l <- 3 to n do
for i <- 1 to n-l+1 do
j <- i + l - 1 { sottostringa X_{i..j} }
if |x_i - x_j| <= 1 then L[i, j] <- 2 + L[i+1, j-1]
else L[i, j] <- MAX(L[i, j-1], L[i+1, j])
return L[1, n]Correttezza. Per induzione sulla lunghezza della sottostringa: le prime due diagonali realizzano i casi base della ricorrenza; per le tre celle da cui dipende sono su diagonali già complete e corrette per ipotesi induttiva, e l'assegnamento implementa il caso corrispondente della ricorrenza, che è corretta per la proprietà (a). Per si restituisce . L'algoritmo è stato confrontato con l'enumerazione di tutte le sottosequenze su vettori casuali di interi piccoli (lunghezza fino a ): stesso risultato in tutti i casi.
Esempio. (). Tabella (triangolo superiore):
| 1: 3 | 2: 5 | 3: 4 | 4: 8 | 5: 4 | 6: 2 | 7: 6 | |
|---|---|---|---|---|---|---|---|
| 1: 3 | 1 | 1 | 3 | 3 | 4 | 5 | 5 |
| 2: 5 | 1 | 2 | 2 | 3 | 3 | 5 | |
| 3: 4 | 1 | 1 | 3 | 3 | 3 | ||
| 4: 8 | 1 | 1 | 1 | 1 | |||
| 5: 4 | 1 | 1 | 1 | ||||
| 6: 2 | 1 | 1 | |||||
| 7: 6 | 1 |
Alcune celle: : , quindi . : , quindi . : , quindi . : , quindi . Una LQPS di lunghezza è , con indici (coppie , e centro ).
Complessità. Si fa una sola sottrazione tra caratteri (il valore assoluto e il confronto con non si contano) per ogni sottostringa di lunghezza , cioè una per ogni diagonale e ogni cella:
(Nella penultima uguaglianza si pone , che va da a .) Per l'esempio : sottrazioni. Con le somme sui valori della tabella il conto resta quadratico; il numero di addizioni e sottrazioni tra i caratteri della stringa è quello sopra. Lo spazio è , riducibile a lineare con tre vettori se serve solo la lunghezza.
Versione ripasso
Testo. è quasi palindroma se per . LQPS = massima lunghezza di una sottosequenza quasi palindroma di . (a) [7 punti] sottostruttura ottima sulle sottostringhe con prova; (b) [5 punti] ricorrenza; (c) [5 punti] pseudocodice bottom-up, correttezza e complessità in numero di addizioni e sottrazioni tra i caratteri.
- Struttura: come la LPS (Allineamento di stringhe e sottosequenza palindroma più lungadue problemi di DP su stringhe con la stessa struttura della LCS. Allineamento ottimo di due stringhe di DNA con matrice di score S e penalità di gap g: C(i,j) = max{C(i-1,j-1) + s(x_i,y_j), C(i-1,j) + g, C(i,j-1) + g}, C(i,0) = i g, C(0,j) = j g; Theta(mn) tempo, spazio Theta(min{m,n}) con un solo vettore se serve solo il costo. Sottosequenza palindroma più lunga (LPS) sullo spazio delle sottostringhe X_(i..j): p(i,j) = 2 + p(i+1,j-1) se x_i = x_j, altrimenti max{p(i+1,j), p(i,j-1)}; scansione per diagonali, n(n-1)/2 confronti.Allineamento di stringhe e sottosequenza palindroma più lunga →) ma con la compatibilità al posto dell'uguaglianza; si tolgono i due estremi, spazio = sottostringhe.
- Proprietà (esiste una LQPS di tale che): : ; : se , altrimenti ; e : , , LQPS di ; altrimenti la più lunga tra LQPS di e di .
- Prova del punto 4: (c'è ); non può essere e (si allungherebbe con ); se solo un estremo è fuori posto lo si sostituisce con o (coppia esterna compatibile, stessa lunghezza); l'interno è ottimo per cut-and-paste. Punto 5: non si possono usare entrambi gli estremi (coppia incompatibile), quindi vive in o in .
- Ricorrenza: ; se , altrimenti ; per : se , altrimenti .
LQPS(X)
n <- |X|
for i <- 1 to n-1 do
L[i,i] <- 1
if |x_i - x_{i+1}| <= 1 then L[i,i+1] <- 2 else L[i,i+1] <- 1
L[n,n] <- 1
for l <- 3 to n do for i <- 1 to n-l+1 do
j <- i + l - 1
if |x_i - x_j| <= 1 then L[i,j] <- 2 + L[i+1,j-1]
else L[i,j] <- MAX(L[i,j-1], L[i+1,j])
return L[1,n]- Correttezza: induzione sulla lunghezza; dipende da diagonali e . Altre scansioni valide: righe da a , colonne con righe decrescenti.
- Esempio : , , , ; LQPS (indici ).
- Costo: una sottrazione per ogni : ( per ).
- Errori tipici: usare invece di ; porre senza controllare la compatibilità; scansione per righe crescenti; contare anche le somme sui valori della tabella tra "addizioni tra i caratteri".