Progettazione di Algoritmi Anno Accademico 2016–2017 Esercizi sull’Analisi di Algoritmi e sulla Tecnica Divide et Impera. Ugo Vaccaro Ricordiamo il seguente risultato per la risoluzione delle più comuni equazioni di ricorrenza: Teorema. La soluzione alla ricorrenza d se n ≤ 1 T (n) = k aT (n/c) + bn altrimenti per a, c, b, k costanti, è se a < ck O(nk ) k O(n log n) se a = ck T (n) = O(nlogc a ) se a > ck Nel caso in cui non si voglia (o non si possa) applicare il risultato di sopra, gli esercizi che seguono si possono risolvere iterando la equazione di ricorrenza che descrive la complessità di tempo dell’algoritmo e deducendo la soluzione. 1. Esercizio: Si consideri il seguente algoritmo: Algoritmo B(n) 1. x = 1 2. IF ((n == 1)||(n == 2) { 3. x=x+1 4. } ELSE { 5. RETURN B(n − 2) } 6. FOR (i = 1, i < n + 1, i = i + 1){ 7. x=x+1 } 8. RETURN B(n − 2) Si derivi una equazione di ricorrenza che descrive la complessità dell’ algoritmo B(n), e la si risolva, usando il metodo di iterazione. 2. Esercizio: Si consideri il seguente algoritmo: Algoritmo(n) 1. IF (n == 1){ 2. RETURN 0 3. } ELSE { 4. RETURN Algoritmo(n/2) } 5. x = 0; i = 0 6. WHILE (x ≤ n) { 7. x=x+1 8. i=i+1 } Si esprima la complessitá di Algoritmo(n) mediante una equazione di ricorrenza e se ne dia una soluzione in termini della notazione O. 1 3. Esercizio: Si consideri il seguente algoritmo: Algoritmo S(n) 1. IF (n == 1) { 2. RETURN 0 3. } ELSE { 4. RETURN S(n/3) } 5. x = 0 6. WHILE (x ≤ 3n3 ) { 7. x=x+3 } 8. RETURN S(n/3) Si derivi una equazione di ricorrenza che descrive la complessità dell’ algoritmo S(n), e la si risolva in termini della notazione O. 4. Esercizio: Si consideri il seguente algoritmo: Algoritmo S(n) 1. IF (n == 1) { 2. RETURN 0 3. } ELSE { 4. RETURN S(n/4) } 5. x = 0 √ 6. WHILE (x ≤ 9 n) { 7. x=x+3 } 8. RETURN S(n/4) Si derivi una equazione di ricorrenza che descrive la complessità dell’ algoritmo S(n), e la si risolva in termini della notazione O. 5. Esercizio: Si consideri il seguente algoritmo: Algoritmo S(n) 1. IF (n == 1) { 2. RETURN 0 3. } ELSE { 4. S(n/4) } 5. x = 0 6. WHILE (x ≤ 3n2 ) { 7. x = x + 3 } 8.RETURN S(n/4) 9. y = 0 10. WHILE (y ≤ 3n) { 11. y = y + 3 } 12. RETURN S(n/4) 13. z = 0 14. WHILE (z ≤ log n){ 15. z = z + 1 } 16. RETURN S(n/5) 2 Si derivi una equazione di ricorrenza che descrive la complessità dell’ algoritmo S(n), e la si risolva, in termini della notazione O. 6. Esercizio: Dato un vettore di interi A = A[0] . . . A[n − 1], progettare un algoritmo basato sulla tecniva Divide et Impera per calcolare la quantità S = A[0]20 + A[1]21 + A[2]22 + · · · A[n − 1]2n−1 . 7. Esercizio. Sia dato un albero binario T con puntatore alla radice z. Ad ogni nodo x dell’albero è associato un campo numerico x.dato. Si scriva un algoritmo basato sulla tecnica Divide et Impera che calcoli la quantità X x:x x.dato. è una foglia di T 8. Esercizio. Sia dato un albero binario T con puntatore alla radice z. Per ogni nodo x dell’albero vale che x.dato ∈ {0, 1}. Si scriva un algoritmo basato sulla tecnica Divide et Impera che calcoli lo XOR (ovvero l’OR esclusivo) dei valori x.dato. 9. Esercizio. Sia dato un albero binario T con puntatore alla radice z. Si scriva un algoritmo basato sulla tecnica Divide et Impera che calcoli il numero di foglie in T . 10. Esercizio. Sia dato un albero binario T con puntatore alla radice z. Si scriva un algoritmo basato sulla tecnica Divide et Impera che calcoli il numero totale di nodi in T . 11. Esercizio. Sia dato un albero binario T con puntatore alla radice z. Si scriva un algoritmo basato sulla tecnica Divide et Impera che calcoli l’altezza di T . 12. Esercizio. Sia dato un albero binario T con puntatore alla radice z. Si scriva un algoritmo basato sulla tecnica Divide et Impera che restituisca valore Vero se tutti i nodi di T hanno due figli (tranne le foglie), valore Falso altrimenti. 13. Esercizio. Sia dato un albero binario T con puntatore alla radice z. Si scriva un algoritmo basato sulla tecnica Divide et Impera che restituisca valore Vero se per ogni nodo x dell’albero vale che il sottoalbero radicato nel figlio sinistro di x ha lo stesso numero di nodi del sottoalbero radicato nel figlio destro di x, Falso atrimenti.. 14. Esercizio. Sia dato un albero binario T con puntatore alla radice z, e sia k > 0 un intero. Ad ogni nodo x dell’albero è associato un campo numerico x.dato. Si scriva un algoritmo basato sulla tecnica Divide et Impera che calcoli la somma dei valori x.dato, per tutti i nodi x nell’albero la cui profondità è ≥ k ed il cui valore x.dato è pari. 15. Esercizio: Sia A = A[1] . . . A[n] un vettore ordinato in senso crescente che è stato shiftato k posizioni a sinistra. Ad esempio, il vettore [15, 18, 28, 30, 35, 42, 1, 7] è un vettore ordinato che è stato shiftato k = 2 posizioni a sinistra, mentre il vettore [30, 35, 42, 1, 7, 15, 18, 28] è un vettore ordinato che è stato shiftato k = 5 posizioni a sinistra. (a) Supponendo di avere A e k in input, dare un algoritmo che determina il minimo in A in tempo O(1) (b) Supponendo di avere solo il vettore A in input, dare un algoritmo che determina il minimo in A in tempo O(log n) 16. Esercizio: Sia A = A[1] . . . A[n] un vettore ordinato in senso crescente che è stato shiftato k posizioni a sinistra. Avendo in input il solo vettore A, progettare un algoritmo basato sulla tecnica Divide et Impera che determini il valore k di cui sopra. 3 17. Esercizio: Sia A un vettore di n interi. Si dice che A è continuo se per ogni i = 1, 2, . . . , n − 1, vale che |A[i + 1] − A[i]| ≤ 1. Si dice zero del vettore un indice k tale che A[k] = 0. Dato un vettore A di n ≥ 2 interi continuo tale che A[1] ≤ 0 e A[n] > 0, provare che A ha almeno uno zero. Progettare un algoritmo basato sulla tecnica Divide et Impera che, dato un vettore A di n ≥ 2 interi continuo e tale che A[1] < 0 e A[n] > 0, trovi uno zero in tempo O(log n). 18. Esercizio: Sia A = A[1] . . . A[n] un vettore di n interi, che possono essere sia positivi che negativi. Si supponga che A[1] ≤ . . . ≤ A[n]. Progettare un algoritmo basato sulla tecnica Divide et Impera che conti il numero di elementi > 0 nel vettore A. Se ne analizzi la complessità. 19. Esercizio: Sia A = A[1] . . . A[n] un vettore di n interi. Progettare un algoritmo basato sulla tecnica Divide et Impera che conti il numero di elementi A[i] nel vettore A, 1 < i < n, per cui valga sia che A[i] = A[i + 1] che A[i] = A[i − 1]. Se ne analizzi la complessità. 20. Esercizio: Sia A = A[1] . . . A[n] un vettore ordinato in senso crescente tale che A[i] ∈ {0, 1}, per ogni i = 1, . . . , n. Progettare un algoritmo basato sulla tecnica Divide et Impera che conti il numero di elementi A[i] nel vettore A, per cui valga che A[i] = 1. Se ne analizzi la complessità. (Il massimo del punteggio lo si ottiene per un algoritmo di complessità O(log n). 21. Esercizio: Siano A ed n numeri naturali positivi. Progettare un algoritmo basato sulla tecnica Divide et Impera che calcoli nA, utilizzando O(log n) addizioni. 22. Esercizio: Sia Sia A = A[1] . . . A[n] un vettore di n interi, tale che A[1] < . . . < A[n]. L’indice i ∈ {2, . . . , n} è detto un salto, se vale che A[i − 1] + 1 < A[i]. Progettare un algoritmo che determini se il generico vettore A ha un salto, e nell’ipotesi che lo abbia, determini attraverso la tecnica Divide et Impera almeno un valore di i per cui A[i − 1] + 1 < A[i]. 4