Sei sulla pagina 1di 7

Algoritmi e Strutture Dati 2

Esercizi Svolti

A.A. 2010/2011

Esercizio 1
Testo: Descrivere in pseudo-codice un algoritmo efficiente che, dato un insieme di n
intervalli I = {Ii = (si , ei ) | 1 i n} e i relativi pesi w(Ii ) N , calcoli il peso
massimo di un sottoinsieme di intervalli non sovrapposti (weighted interval scheduling
problem).
Mostrarne inoltre il funzionamento sul seguente insieme di intervalli.
Istanza:
I1
I2
I3
I4

= (1, 4)
= (3, 5)
= (0, 6)
= (4, 7)

w(I1 ) = 2
w(I2 ) = 3
w(I3 ) = 4
w(I4 ) = 3

I5
I6
I7
I8

= (3, 8)
= (5, 9)
= (6, 10)
= (8, 11)

w(I5 ) = 5
w(I6 ) = 5
w(I7 ) = 5
w(I8 ) = 7

Si assuma che ciascun intervallo includa lestremo sinistro ma non includa lestremo
destro (cio`e gli intervalli (2, 5) e (5, 10) non sono da considerarsi sovrapposti).
Svolgimento: Per semplicit`
a assumiamo che gli intervalli siano ordinati in senso non
decrescente per tempo di fine (cio`e per estremo destro). Altrimenti tali intervalli possono
essere facilmente ordinati in tempo O(n log n).
Assumiamo inoltre che sia disponibile un vettore p[i] che indica, se esiste, lindice
dellultimo intervallo che termina prima dellinizio dellintervallo Ii o 0, altrimenti. In
altre parole:
(
0
se ej > si per ogni 1 j < i
p[i] =
max1j<i {j | ej si } altrimenti
dove, ricordiamo, si e ei sono, rispettivamente, gli estremi sinistro e destro dellintervallo
Ii (cio`e Ii = (si , ei ) per ogni 1 i n). Il vettore p[i] pu`o essere facilmente calcolato
dalla sequenza degli intervalli (ordinati in senso crescente per tempo di fine/estremo
destro) in tempo (n).

Lalgoritmo impiega la tecnica della programmazione dinamica ed `e descritto in pseudocodice dallAlg. 1


Algorithm 1: Weighted-Interval-Scheduling
Input : Una sequenza I = h(s1 , e1 ), . . . , (sn , en )i di intervalli tale che
e1 e2 . . . en e una funzione peso w : I N ;
Output: Il peso massimo di un sottoinsieme di intervalli a coppie non sovrapposti;
1 A[0] 0;
2 for i 1 to n do
3
A[i] max(A[i 1], w(Ii ) + A[p[i]]);
4 end
5 return A[n];
Dallinstanza data nel testo (gi`
a ordinata per tempo di fine), calcoliamo il seguente
vettore p[i]:
p= 0 0 0 1 0 2 3 5
Quindi il vettore A[i] verr`
a iterativamente riempito come di seguito:
caso base A[0] = 0
1a iter. A[1] = max(0, 2 + 0) = 2
2a iter. A[2] = max(2, 3 + 0) = 3
3a iter. A[3] = max(3, 4 + 0) = 4
4a iter. A[4] = max(4, 3 + 2) = 5
5a iter. A[5] = max(5, 5 + 0) = 5
6a iter. A[6] = max(5, 5 + 3) = 8
7a iter. A[7] = max(8, 5 + 4) = 9
8a iter. A[8] = max(9, 7 + 5) = 12
Il peso massimo sar`
a, quindi, A[n] = A[8] = 12 (corrispondente agli intervalli {I1 , I4 , I8 }).

Esercizio 2
Testo: Scrivere un equazione di ricorrenza di programmazione dinamica per stabilire
se esiste un cammino di lunghezza al pi`
u 4 tra un vertice i e un vertice j di un grafo
G = (V, E) non pesato (orientato o non orientato).
(k)

Svolgimento: Sia Ti,j,p = Vero se esiste un cammino di lunghezza al pi`


u p tra i vertici
(k)

i e j passando soltanto per alcuni dei vertici {1, . . . , k}, e Ti,j,p = Falso altrimenti.
Lequazione di programmazione dinamica `e la seguente (ricordiamo che la lunghezza
(k)
di un cammino `e definita come il numero di archi che lo compongono, quindi Ti,j,0 `e
sempre uguale a Falso):
Casi base
(0)
Ti,j,p

(
Vero
=
Falso

se (i, j) E e p > 0
altrimenti

(k)

Ti,j,0 = Falso
Caso generale

(k)
Ti,j,p

(k1)

Ti,j,p
(k1)
(k1)
= or Ti,k,p
and Tk,j,p2
1

(cio`e il vertice k non appartiene al cammino)


con p1 + p2 p
(cio`e il vertice k appartiene al cammino)
(n)

Il costo della soluzione ottima sar`a data da Ti,j,4 , dove n = |V |.


Nota: nello svolgimento di questi esercizi si raccomanda di indicare sempre, oltre allequazione di ricorrenza nei suoi casi base e generale, anche il significato che si attribuisce
(k)
alla variabile matematica in gioco (Ti,j,p , in questo caso) e come `e calcolato lottimo del
problema. Tutti questi elementi, infatti, sono determinanti per la corretta esposizione
dello svolgimento.

Esercizio 3
Testo: Descrivere in pseudocodice una procedura di ricostruzione e stampa di un
cammino per il seguente problema:
Problema 1. Esistenza di un cammino alternato.
Input: Un grafo G = (V, E), una funzione col : V {rosso, nero};
Output: Vero se esiste un cammino da un vertice i a un vertice j che alterna i colori
dei vertici, Falso altrimenti.
(k)

Svolgimento: Sia Ti,j = Vero se esiste un cammino che alterna i colori dei vertici tra
(k)

i e j passando soltanto per alcuni dei vertici {1, . . . , k}, e Ti,j = Falso altrimenti.
Lequazione di programmazione dinamica, come visto a lezione, `e:
Caso base
(0)
Ti,j

(
Vero
=
Falso

se (i, j) E e col(i) 6= col(j)


altrimenti

Caso generale
(k)

Ti,j = or

( (k1)
Ti,j
(k1)
Ti,k

(cio`e il vertice k non appartiene al cammino)


and

(k1)
Tk,j

(cio`e il vertice k appartiene al cammino)

La procedura di stampa `e composta da due funzioni ricorsive. La prima (chiamata


(k0 )
pred) stabilisce, data una terna (i0 , j 0 , k 0 ) tale che Ti0 ,j 0 = Vero, quale caso si `e
verificato durante il calcolo dellequazione di ricorrenza e restituisce il predecessore di j 0
sul cammino a vertici alternati da i0 a j 0 . La seconda (chiamata Stampa-Percorso)
ricostruisce (e stampa) a ritroso, tramite successive chiamate alla prima funzione, lintero
percorso da un vertice i0 a un vertice j 0 .
Si noti che le procedure pred e Stampa-Percorso sono corrette se e soltanto se
(k0 )
sono chiamate, rispettivamente, su una terna (i0 , j 0 , k 0 ) tale che Ti0 ,j 0 = Vero e su una
(n)

coppia (i0 , j 0 ) tale che Ti0 ,j 0 = Vero (precondizioni). In altre parole, sono corrette se e
soltanto se esiste un percorso a vertici di colori alternati tra i vertici i0 e j 0 .
Chiaramente, il percorso (a vertici di colori alternati) da un vertice i a un vertice j si
ottiene con la chiamata Stampa-Percorso(i, j).

Algorithm 2: pred : i0 , j 0 , k 0 7 p
(k0 )

Input : Tre vertici i0 , j 0 , k 0 tali che Ti0 ,j 0 = Vero;


Output: Il vertice p che precede j 0 in un cammino a vertici di colori alternati da i0
a j 0 passando solamente da alcuni vertici dellinsieme {1, . . . , k 0 };
0
if k = 0 then
0
/* Dato che Ti(k0 ,j=0)
= Vero (per precondizione), allora per la definizione del caso
0
base si ha che (i0 , j 0 ) E e col(i0 ) 6= col(j 0 )

2
3
4

return ;
else // cio`e k0 > 0
(k0 1)
if Ti0 ,j 0 = Vero then // cio`e k0 non appartiene al cammino
/* Il predecessore di j 0 sul cammino da i0 a j 0 `e il predecessore di j 0 sul
cammino da i0 a j 0 senza considerare k0

5
6

return
1) ;
else // cio`e k appartiene al cammino
/* k0 appartiene al cammino da i0 a j 0 , quindi il predecessore di j 0 `e da
return pred(k 0 , j 0 , k 0 1) ;

Algorithm 3: Stampa-Percorso (i0 , j 0 )


(n)

1
2
3
4
5
6
7

*/

pred(i0 , j 0 , k 0

ricercare sul cammino da k0 a j 0


7

*/

i0

Input : Due vertici i0 , j 0 tali che Ti0 ,j 0 = Vero;


Output: Stampa (a video) un cammino a vertici di colori alternati da i0 a j 0 ;
if i0 = j 0 then
Stampa il vertice i0 ;
else
p pred(i0 , j 0 , n) ;
Stampa-Percorso(i0 , p) ;
Stampa il vertice j 0 ;
end

*/

Esercizio 4
Testo: Definire unequazione di ricorrenza di Programmazione Dinamica per la soluzione del seguente problema:
Problema 2. Longest Increasing Subsequence (LIS).
Input: Una sequenza S = hs1 , s2 , . . . , sn i di numeri naturali;
Output: La lunghezza massima di una sottosequenza monotona crescente di S.
Svolgimento: Lidea alla base della risoluzione del problema `e quella di determinare,
per ogni elemento si della sequenza S la lunghezza massima di una sottosequenza monotona crescente che termina (esattamente) con lelemento si . Chiaramente, la soluzione
finale del problema sar`
a, poi, il massimo delle lunghezze cos` determinate.
Sia L[i] la lunghezza massima di una sottosequenza monotona crescente di S che termina con lelemento si . Si assuma che L[0] (cio`e la lunghezza massima di una sottosequenza
della sequenza composta da 0 elementi) sia uguale a 0. Per capire come calcolare L[i]
proviamo ad analizzare la sottostruttura di una soluzione ottima del problema. Si noti
che la pi`
u lunga sottosequenza monotona crescente sj1 sj2 . . . sjk di S che termina con si `e
sicuramente composta (banalmente) dallelemento si (e quindi ha lunghezza almeno pari
a 1). La parte che precede lelemento si (= sjk ) nella pi`
u lunga sottosequenza monotona
crescente (cio`e sj1 sj2 . . . sjk1 ) sar`
a una pi`
u lunga sottosequenza monotona crescente del
prefisso s1 s2 . . . si1 che termina con un elemento sjk1 tale che sjk1 < si . Infatti se, per
assurdo, cos` non fosse (cio`e se sj1 sj2 . . . sjk1 non fosse una pi`
u lunga sottosequenza monotona crescente che termina con lelemento sjk1 ) allora esisterebbe una sottosequenza
monotona crescente pi`
u lunga di sj1 sj2 . . . sjk che contraddice lipotesi di ottimalit`a di
sj1 sj2 . . . sjk .
Questo ragionamento si traduce immediatamente nella seguente equazione di ricorrenza:
Caso base
L[0] = 0
Caso generale
L[i] = 1 + max{L[j] | j < i and sj < si }
Per quanto gi`
a detto, la soluzione del problema (cio`e la lunghezza della pi`
u lunga
sottosequenza monotona crescente di S) sar`a pari a max{L[i] | 1 i n} mentre il
tempo di calcolo necessario `e pari a O(n2 + n), cio`e O(n2 ) (si noti infatti che il tempo
richiesto per calcolare ciascun valore L[i] `e pari a O(i)).

Esercizio 5
Testo: Definire unequazione di ricorrenza di Programmazione Dinamica per la soluzione del seguente problema:
Problema 3. Longest Common Increasing Subsequence (LCIS).
Input: Due sequenza S = hs1 , s2 , . . . , sn i e T = ht1 , t2 , . . . , tm i di numeri naturali;
Output: La lunghezza massima di una sottosequenza monotona crescente comune a S e
T.
Svolgimento: La soluzione di questo problema combina le idee usate per risolvere il
problema della Longest Common Subsequence (LCS) e del precedente Longest Increasing
Subsequence (LIS).
Infatti, sia L[i, j] la lunghezza di una sottosequenza monotona crescente comune a S
e T che termina (esattamente) con gli elementi si e tj . Se si e tj sono diversi, allora
una sottosequenza comune che termina con si e tj , chiaramente, non pu`o esistere e, in
questo caso, assumiamo di porre L[i, j] uguale a 0. Come per il problema precedente e
per il problema della LCS assumiamo che L[i, 0] e L[0, j] siano uguali a 0.
Lequazione di Programmazione Dinamica risultante sar`a la seguente:
Caso base
L[0, 0] = 0
L[i, 0] = 0
L[0, j] = 0
Caso generale
(
1 + max{L[i0 , j 0 ] | (i0 < i) (j 0 < j) (si0 = tj 0 ) (si0 < si )}
L[i, j] =
0

se si = tj
altrimenti

Essenzialmente il caso generale dellequazione di ricorrenza pone L[i, j] uguale a 0 se i


due elementi si e tj sono differenti (per il motivo spiegato sopra) o, altrimenti, aggiunge
1 alla lunghezza della pi`
u lunga sottosequenza monotona crescente comune ai prefissi
s1 . . . si1 e t1 . . . tj1 che termina con un elemento strettamente minore di si (e tj , che
`e uguale a si ).
Si noti che la condizione (si0 = tj 0 ) `e in realt`a superflua perche se si0 6= tj 0 allora L[i0 , j 0 ]
sarebbe uguale a 0 e indicherebbe che non esiste nessuna sottosequenza comune che
termina esattamente con gli elementi di quelle posizioni. Loperatore max andrebbe
quindi a preferire (se esiste) qualsiasi altra coppia di posizioni (i00 , j 00 ) strettamente
minori di, rispettivamente, i e j tale che si00 = tj 00 .
La soluzione del problema sar`
a, invece:
max L[i, j]

1in
1jm

Considerato che il tempo per calcolare ciascun elemento L[i, j] `e O(ij), il tempo di
calcolo totale per risolvere il problema `e O(n2 m2 ).