Schema generale di un algoritmo divide-et-impera risolviDivImp(Problema P di dimensione n) { if(n < n0) risolvi P direttamente Università di Torino – Facoltà di Scienze MFN Corso di Studi in Informatica Curriculum SR (Sistemi e Reti) else { dividi P in h sottoproblemi P1, P2, ... , Ph di dimensioni risp. n1, n2, ... , nh; Algoritmi e Laboratorio a.a. 2009-10 Lezioni risolviDivImp(P1); risolviDivImp(P2); ... risolviDivImp(Ph); prof. Elio Giovannetti Lez 30 –Algoritmi divide-et-impera, teorema fondamentale delle ricorrenze. versione 26/11/09 Quest' opera è pubblicata sotto una Licenza Creative Commons Attribution-NonCommercial-ShareAlike 2.5. } combina le soluzioni di P1, P2, ... , Ph in modo da ottenere la soluzione di P 26/11/09 Esempio: quicksort E. Giovannetti - AlgELab-09-10 - Lez.30 2 Esempio: mergesort su array quicksort(sequenza S) { if(dimensione di S < 2) non fare nulla; else { dividi S nelle due sequenze S1 ed S2 (partizione); quicksort(S1); quicksort(S2); } } mergesort(array A) { if(dimensione di A < 2) non fare nulla; else { dividi A nelle due sequenze A1 e A2; mergesort(A1); mergesort(A2); combina – tramite merge – le soluzioni di A1 e A2 } } • la scomposizione del problema in sottoproblemi è effettuata dall'algoritmo di partizione rispetto al perno, di costo lineare; • la ricombinazione delle soluzioni dei sottoproblemi non richiede alcuna computazione, quindi è di costo nullo. • la scomposizione del problema in sottoproblemi è un calcolo banale, di costo costante; • la ricombinazione delle soluzioni dei sottoproblemi per ottenere la soluzione del problema è effettuata dalla fusione ordinata (merge), di costo lineare. 26/11/09 E. Giovannetti - AlgELab-09-10 - Lez.30 3 Esempio: mergesort su lista concatenata ⎡ a11 a12 ⎢a ⎢ 21 a 22 ⎢a 31 a 32 ⎢ ⎣a 41 a 42 4 a13 ... ... ... a14 ⎤ ⎡ b11 ... ⎥⎥ ⎢⎢b 21 × ... ⎥ ⎢ b 31 ⎥ ⎢ a 44 ⎦ ⎣b 41 b12 b13 b 22 ... b 32 ... b 42 ... b14 ⎤ ... ⎥⎥ =C ... ⎥ ⎥ b 44 ⎦ cij = a i1b1j + a i2 b 2j + ... + a i4 b 4j • la scomposizione del problema in sottoproblemi richiede lo scorrimento di L, di costo lineare; • la ricombinazione delle soluzioni dei sottoproblemi è effettuata dalla fusione ordinata (merge), di costo lineare. E. Giovannetti - AlgELab-09-10 - Lez.30 E. Giovannetti - AlgELab-09-10 - Lez.30 Moltiplicazione di matrici quadrate di lato n. mergesort(lista L) { if(dimensione di L < 2) non fare nulla; else { dividi L nelle due liste L1 ed L2; mergesort(L1); mergesort(L2); combina – tramite merge – le soluzioni di L1 e L2 } } 26/11/09 26/11/09 5 Il calcolo di ogni elemento della matrice prodotto richiede n prodotti ed n-1 somme, quindi un tempo Θ(n). Per calcolare tutti gli n2 elementi della matrice prodotto occorre quindi un tempo T(n) = Θ(n3). Si può fare meglio ? 26/11/09 E. Giovannetti - AlgELab-09-10 - Lez.30 6 1 Moltiplicazione di matrici quadrate di lato n. Poniamo: ⎡ a11 a12 ⎢a ⎢ 21 a 22 ⎢ ... ... ⎢ ⎣a n1 a n2 ⎡ b11 ⎢b ⎢ 21 ⎢ ... ⎢ ⎣b n1 b12 b 22 ... b n2 ... a1n ⎤ ... a 2n ⎥⎥ ⎡ A11 = ... ... ⎥ ⎢⎣A 21 ⎥ ... a nn ⎦ ... b1n ⎤ ... b 2n ⎥⎥ ⎡ B11 = ... ... ⎥ ⎢⎣B21 ⎥ ... b nn ⎦ Per applicare la tecnica divide et impera si noti che: C12 ⎤ ⎡C C = ⎢ 11 ⎥ ⎣C 21 C 22 ⎦ A12 ⎤ A 22 ⎥⎦ dove: C11 = A11B11 + A12B21; C12 = A11B12 + A12B22; C21 = A21B11 + A22B21; C22 = A21B12 + A22B22; B12 ⎤ B 22 ⎥⎦ dove ovviamente Aij e Bij sono matrici di dim. n/2 × n/2 26/11/09 E. Giovannetti - AlgELab-09-10 - Lez.30 7 26/11/09 Applichiamo la tecnica divide et impera E. Giovannetti - AlgELab-09-10 - Lez.30 equazione di ricorrenza per il tempo di calcolo: T(1) = 1 se n > 1: T(n) = 8T(n/2) + tempo_divisione + tempo_combinazione • tempo_divisione = costante; • tempo_combinazione = tempo necessario per eseguire 4 somme di matrici di dim. n/2 × n/2; • ognuna di esse richiede evidentemente (n/2)2 somme o diff.; (tante quanti sono gli elementi di una matrice); • il tempo totale di divisione e ricombinazione è quindi Θ(n2). Quindi 9 T(m) = 8T(m/2) + Θ(m2) poniamo n = 2k T(n) = 8T(n/2) + n2 = T(n/2) = 8T(n/22) + n2/22 = 8(8T(n/22) + n2/22) + n2 = T(n/22) = 8T(n/23) + n2/24 = 82 T(n/22) + 8(n2/22) + n2 = = 82(8T(n/23) + n2/24) + 8(n2/22) + n2 = = 83 T(n/23) + 82(n2/24) + 8(n2/22) + n2 = T(n/23) = 8T(n/24) + n2/26 = 83 (8T(n/24) + n2/26) + 82(n2/24) + 8(n2/22) + n2 = = 84 T(n/2 T( /24) + 83(n ( 2/26) + 82(n ( 2/24) + 8(n 8( 2/22) + n2 = ... = 8k T(1) + 8k-1(n2/22(k-1)) + ... + 83(n2/26) + 82(n2/24) + 8(n2/22) + n2 = = (2k)3 + n2(8k-1/22(k-1) + ... + 83/26 + 82/24 + 8/22 + 1) = = n3 + n2(2k-1 + ... + 23 + 22 + 2 + 1) = 26/11/09 n2(2k – 1) = 26/11/09 E. Giovannetti - AlgELab-09-10 - Lez.30 10 matrice moltiplica(matrice A, matrice B) { matrice C sarà il risultato; if(dimensioneMatrici == 1) c11 = a11 * b11; else { vedi ad es. dispense di Matematica Discreta: dividi A nelle matrici A11, A12, A21, A22; dividi B nelle matrici B11, B12, B21, B22; matrice X1 = moltiplica(A11 + A22, B11 + B22); matrice X2 = moltiplica(A21 + A22, B11); ... matrice X7 = moltiplica(A11 - A22, B21 + B22); C11 = X1 + X4 – X5 + X7; C12 = X3 + X5; C21 = X2 + X4; C22 = X1 + X3 – X2 + X6; n3 + n2(n – 1) = 2n3 - n2 = Θ(n3) Nessun vantaggio ! E. Giovannetti - AlgELab-09-10 - Lez.30 T(n) = 8T(n/2) + Θ(n2) per n > 1 Moltiplicazione di matrici quadrate: metodo di van Strassen. Risoluzione: difficile ... ? = n3 + 8 Ricaviamo l'equazione di ricorrenza: matrice moltiplica(matrice A, matrice B) { matrice C sarà il risultato; if(dimensioneMatrici == 1) c11 = a11 * b11; else { dividi A nelle matrici A11, A12, A21, A22; dividi B nelle matrici B11, B12, B21, B22; C11 = moltiplica(A p p 11, B11) + moltiplica(A 12, B21) ; C12 = moltiplica(A11, B12) + moltiplica(A12, B22) ; C21 = moltiplica(A21, B11) + moltiplica(A22, B21) ; C22 = moltiplica(A21, B12) + moltiplica(A22, B22) ; } return C; } Si ha un vantaggio ? La risposta alla fine. eq. di ricorrenza: T(1) = 1 T(n) = 8T(n/2) + ? per n > 1 26/11/09 E. Giovannetti - AlgELab-09-10 - Lez.30 11 } } return C; 26/11/09 E. Giovannetti - AlgELab-09-10 - Lez.30 12 2 Metodo di van Strassen: visione astratta. Metodo di van Strassen: tempo di calcolo. risolviDivImp(moltiplicazione delle matrici A e B di dim. n) { if(n == 1) risolvi immediatamente; else { dividi il problema in 7 sottoproblemi di moltiplicazione di matrici di dimensione n/2 × n/2 X1 = risolviDivImp(sottoproblema1); ... X7 = risolviDivImp(sottoproblema7); } } combina le soluzioni X1, ..., X7 in modo da ottenere la soluzione C del problema; 26/11/09 E. Giovannetti - AlgELab-09-10 - Lez.30 equazione di ricorrenza per il tempo di calcolo: T(1) = 1 T(n) = 7T(n/2) + tempo_divisione + tempo_combinazione (n>1) • tempo_divisione: calcolo di A11 + A22, B11 + B22, ...: sono 10 somme o differenze di matrici di dim. n/2 × n/2; • tempo_combinazione: C11 = X1 + X4 ...: sono 8 somme o differenze di matrici di dim. n/2 × n/2; • ognuna di esse richiede evidentemente (n/2)2 somme o diff.; (tante quanti sono gli elementi di una matrice); • il tempo totale di divisione e ricombinazione è quindi Θ(n2). Quindi 13 26/11/09 T(n) = 7T(n/2) + Θ(n2) per n > 1 E. Giovannetti - AlgELab-09-10 - Lez.30 14 Algoritmi divide-et-impera Algoritmi divide-et-impera a partizione bilanciata • Nel quicksort, nel caso generico, le dimensioni dei due sottoproblemi non sono in proporzione fissa; si ha soltanto che la somma di esse è uguale alla dimensione del problema; l'equazione di ricorrenza è quindi • La suddetta caratteristica del mergesort, del caso migliore del quicksort e dell'algoritmo di van Strassen viene detta partizione bilanciata. T(n) = T(h) + T(n-h) + tempo_partizione(n) (per n > 1); • Nel mergesort, g , nel caso migliore g del quicksort, q , e nella moltiplicazione di matrici con l'algoritmo di van Strassen, invece, i sottoproblemi hanno tutti la stessa dimensione, che è una ben determinata frazione del problema: mergesort: quicksort-best: tentativo prodotto di matrici: van Strassen: 26/11/09 T(n) = 2T(n/2) + T(n) = 2T(n/2) + T(n) = 8T(n/2) + T(n) = 7T(n/2) + E. Giovannetti - AlgELab-09-10 - Lez.30 cn cn cn2 cn2 15 26/11/09 E. Giovannetti - AlgELab-09-10 - Lez.30 16 Equazione di ricorrenza a partizione bilanciata Equazioni di ricorrenza a partizione bilanciata: soluzione generale. (versione semplificata, e leggermente ristretta, del teorema fondamentale delle ricorrenze, o teorema dell'esperto, o master theorem, riportato sul libro di t t vedi testo; di anche, h sulle ll di dispense di M Matematica t ti Di Discreta, t una versione ancora un po' più ristretta) E. Giovannetti - AlgELab-09-10 - Lez.30 • L'equazione di ricorrenza è quindi: T(n) = aT(n/b) + f(n) • Nei casi interessanti f(n) è polinomiale; consideriamo allora solo equazioni della forma: con s ≥ 0 T(n) = aT(n/b) + cns Il teorema master. 26/11/09 • Gli algoritmi divide-et-impera a partizione bilanciata sono gli algoritmi divide-et-impera tali che il problema di dimensione n viene scomposto in a problemi di dimensione n/b (dove non necessariamente a = b). 17 T(1) = d T(n) = aT(n/b) + cns per n > 1 dove: d ≥ 0: il lavoro sul problema di dimensione 1 può essere nullo; a è un intero ≥ 1: è il numero delle chiamate ricorsive; b > 1: i sottoproblemi devono essere più piccoli del problema; c > 0: è necessario almeno un'altro un altro tempo oltre al tempo impiegato dalle chiamate ricorsive (almeno quello del test per stabilire se si è nel caso base); trattandosi di coefficiente di addendo, non è restrittivo porre c = 1; s ≥ 0: il tempo al di fuori delle chiamate ricorsive può essere costante, cioè s = 0 (se divisione e ricombinazione sono entrambe operazioni banali in tempo costante); altrimenti esso cresce con n, cioè s > 0. 26/11/09 E. Giovannetti - AlgELab-09-10 - Lez.30 18 3 Rappresentazione grafica Riassunto delle prossime slides ms = T(m) a T(m/b) T(m/b) ... ... T(m/b) Il tempo di calcolo per un problema di dimensione m è: • tempo ms per eseguire il corpo della procedura escluse le chiamate ricorsive; + • i tempi per le a chiamate ricorsive, ognuna su un problema di dimensione m/b. 26/11/09 E. Giovannetti - AlgELab-09-10 - Lez.30 19 Riassunto delle prossime slides Consideriamo l'albero di ricorsione (cioè delle chiamate ricorsive): • Ogni chiamata, per n > 1, effettua a chiamate ricorsive: all'i-esimo livello dell'albero si hanno quindi ai nodi (chiamate ricorsive). • La dimensione dei sottoproblemi diminuisce di un fattore b ad ogni successivo livello: all'i-esimo livello la dimensione è q quindi n/bi. • Il lavoro compiuto per ogni sottoproblema di livello i è quindi (n/bi)s. • Il lavoro totale al livello i è pertanto ai(n/bi)s, che è = (a/bs)i ns. • Ponendo bk = n, cioè k = logbn, si raggiunge il caso base T(1) dopo k livelli, cioè l'altezza dell'albero di ricorsione è k. • Il lavoro totale è dato dalla somma di tutti i livelli, cioè per i che varia da 0 a k (= logbn): 26/11/09 E. Giovannetti - AlgELab-09-10 - Lez.30 20 Con il solito metodo degli sviluppi successivi: Il tempo totale è quindi: caso 1: a < bs: somma di termini decrescenti, conta il primo termine (i = 0): T(n) = Θ(ns ⋅ 1) = Θ(ns) T(n) bs: caso 2: a > somma di termini crescenti, conta l'ultimo termine (i = k) T(n) = Θ(ak(n/bk)s) = Θ(ak) = Θ(alogbn) = Θ(nlogba) sostituendo a T(n) l'albero a secondo membro dell'equazione della slide 19, con n al posto di m, banalmente si ottiene ... (vedi slide seguente) caso 2: a = bs: somma di termini costanti = 1, contano tutti i termini: T(n) = ns(k+1) = ns (logb n + 1) = Θ(ns logb n) 26/11/09 E. Giovannetti - AlgELab-09-10 - Lez.30 21 26/11/09 E. Giovannetti - AlgELab-09-10 - Lez.30 ns (n/b)s a T(n/b) T(n/b) T(n/b) ... ... E. Giovannetti - AlgELab-09-10 - Lez.30 = a T(n/b2) T(n/b) Sostituendo ciascun sottoalbero T(n/b) con l'albero secondo membro dell'equazione della slide 19, con n/b al posto di m, cioè ... 26/11/09 22 23 T(n/b2) ... ... T(n/b2) si ottiene ... (vedi slide seguente) 26/11/09 E. Giovannetti - AlgELab-09-10 - Lez.30 24 4 Nota: per m = n/b si ha ms = (n/b)s = ns/bs ns a ns/bs ... a a T(n/b2) T(n/b2) ... T(n/b3) ... ... T(n/b3) T(n/b3) T(n/b2) si ottiene ... (vedi slide successiva) ... Sostituendo a loro volta i sottoalberi T(n/b2) con le loro espansioni ... 26/11/09 = T(n/b2) ns/bs ... ... a T(n/b2) (n/b2)s E. Giovannetti - AlgELab-09-10 - Lez.30 25 26/11/09 E. Giovannetti - AlgELab-09-10 - Lez.30 26 Nota: per m = n/b2 si ha ms = (n/b2)s = ns/(bs)2 Per m = n/b3 si ha ms = (n/b3)s = ns/(bs)3 ns ns a ns/bs ... ... a ns/(bs)2 ns/(bs)2 a ... ns/bs ns/bs a a ns/(bs)2 a ns/(bs)2 ... T(n/b3) a a a T(n/b3) ns/(bs)2 ns/(bs)3 E. Giovannetti - AlgELab-09-10 - Lez.30 27 ns/(bs)2 ns/(bs)3 a n /(b ) a ns/(bs)3 ... ... s s i n /(b ) 26/11/09 ... s a n /(b ) a liv. 3: a3 nodi ns/(bs)3 ns/(bs)3 ns/(bs)3 s i n /(b ) s ... liv. i: ai nodi s 2 n /(b ) ... ... ... a ... ... ... ... E. Giovannetti - AlgELab-09-10 - Lez.30 28 ... E. Giovannetti - AlgELab-09-10 - Lez.30 a a ns/bs ns/bs livello 2: a2 nodi s 2 a ns/(bs)3 Poniamo n = bk, cioè k = logb n. a s ns/(bs)2 ns livello 1: a nodi a s 2 ns/(bs)2 ... ... ns s a ... ns/(bs)3 26/11/09 Per m = n/bi si ha ms = (n/bi)s = ns/(bs)i ns/bs ns/bs ... ... ... ... T(n/b3) Espandendo a loro volta i sottoalberi T(n/b3) si ottiene ... 26/11/09 ... a ... ... a s s 2 n /(b ) a ... ... ns/(bs)i ns/(bs)i 29 s s 2 n /(b ) a ns/(bs)3 T(n/bk) 26/11/09 ... ns/bs s s 2 n /(b ) ns/(bs)3 a ... ... a s n /(b ) ... ns/(bs)3 T(n/bk) s 2 ns/(bs)3 T(n/bk) E. Giovannetti - AlgELab-09-10 - Lez.30 a ... ... ... ns/(bs)2 a ... T(n/bk) 30 5 Allora T(n/bk) = T(1) = 1 ns a ns/bs s 2 n /(b ) a ns/(bs)3 1 s s 2 n /(b ) ... ns/(bs)3 a 1 s 2 ns/(bs)3 1 s 2 n /(b ) a ... ... ... E. Giovannetti - AlgELab-09-10 - Lez.30 s s 2 n /(b ) ... ns/(bs)3 1 ns/(bs)2 a ns/(bs)3 1 ... ultimo livello = 26/11/09 a ... ... ... a ... 1 E. Giovannetti - AlgELab-09-10 - Lez.30 32 ns/bs ... ns/(bs)2 ns/(bs)2 a a liv. 3: a3 nodi ns/(bs)3 ns/(bs)3 ... ... ... foglie = E. Giovannetti - AlgELab-09-10 - Lez.30 cioè appunto: ... 1 foglie 33 26/11/09 E. Giovannetti - AlgELab-09-10 - Lez.30 Il tempo totale E. Giovannetti - AlgELab-09-10 - Lez.30 34 Guardiamo di nuovo l'albero di ricorsione: • Come al solito, il tempo di calcolo totale è la somma dei tempi contenuti in tutti i nodi dell'albero. • Per valutare tale somma osserviamo che ad ogni successivo livello di ricorsione: • il numero dei nodi si moltiplica per a; • la dimensione del problema di ciascun nodo si divide per b; • il tempo di lavoro di ciascun nodo si divide per bs. • Quindi d ill peso temporale l di d un intero livello l ll si moltiplica l l per a/bs ogni volta che si scende di un livello. • se a/bs < 1, i contributi dei livelli successivi vanno via via diminuendo e, come vedremo, domina quello della radice; • se a/bs > 1, i contributi dei livelli successivi vanno via via aumentando e, come vedremo, domina quello delle foglie; • se a/bs = 1, i contributi dei livelli successivi sono tutti uguali fra di loro e occorre quindi tenere conto di tutti. 26/11/09 liv. 3: a3 nodi ns/(bs)3 ns/(bs)3 a livello 2: a2 nodi foglie = ns/(bs)2 n /(b ) si ha: ... ... ak nodi s 2 Avendo posto ... ... ns/(b ) a 26/11/09 a a s 3 ns/(bs)3 ... a s La proprietà dei logaritmi da ricordare. livello 1: a nodi ns/(bs)2 n /(b ) a2 k+1 livelli da 0 a k, cioè logbn + 1 livelli, cioè Θ(logbn) livelli 31 ns a livello 2: s 2 ... ... 1 Ricorda una proprietà dei logaritmi: ns/bs ns/bs ... ... s ... a a Qual è l'altezza dell'albero ? Quante sono le foglie ? 26/11/09 livello 1: a nodi a s n /(b ) ... ns/(bs)3 ... ... a s a ns/bs ns/bs ... ... a s ns 35 ns a ns/bs livello 1: a nodi ... ... a s s 2 n /(b ) a ns/(bs)3 s s i n /(b ) 26/11/09 ns/bs ... n /(b ) a liv. 3: a3 nodi ns/(bs)3 ns/(bs)3 ns/(bs)3 s a livello 2: a2 nodi s s i n /(b ) s 2 s n /(b ) ... ... ... ... liv. i: ai nodi s 2 ... E. Giovannetti - AlgELab-09-10 - Lez.30 a ns/(bs)2 a ... ... ns/(bs)i ns/(bs)i 36 6 Il tempo totale (continua) Ricorda una proprietà dei logaritmi: ns a ns/bs livello 1: a nodi ... ... a s s 2 n /(b ) a ns/(bs)3 1 ... s livello 2: s 2 n /(b ) ns/(bs)3 a a2 ... a nodi ... ... s s 2 n /(b ) liv. 3: a3 nodi ns/(bs)3 ns/(bs)3 ultimo livello = ak foglie = 26/11/09 ns/bs a ... ... ... foglie = E. Giovannetti - AlgELab-09-10 - Lez.30 ns/(bs)2 a ... 1 foglie 37 • Notiamo infatti, guardando l'albero, che: • contributo del modo radice = • contributo delle foglie = numero delle foglie = • Quindi è una somma (dove il numero degli addendi dipende da n) in cui gli addendi intermedi hanno valori compresi fra quelli degli estremi. Se i due estremi sono diversi, ll'andamento andamento della somma è l'andamento del maggiore dei due (per la dimostrazione vedi le due slides successive): • se a < bs, cioè logba < s, domina la radice: • se a > bs, cioè logba > s, vincono le foglie: • se a = bs, cioè logba = s, tutti i livelli danno lo stesso contributo ns, e quindi il tempo totale è: T(n) = ns • num_di_livelli, cioè: 26/11/09 38 Dimostrazione (fine). Andamento della somma (per a ≠ bs): dimostrazione. Guardando l'albero, vediamo che il contributo del livello i è: E. Giovannetti - AlgELab-09-10 - Lez.30 Dunque, se q ≠ 1, cioè a ≠ bs : I due casi dove, per semplicità di scrittura, abbiamo posto q = a/bs. Si noti che q è una costante, cioè non dipende da n. La somma di tutti i livelli è quindi, quindi se k = logb n: Se q ≠ 1, cioè a ≠ bs, cioè s ≠ logba è l'ultimo termine della successione c.v.d. quindi 26/11/09 Naturalmente E. Giovannetti - AlgELab-09-10 - Lez.30 39 26/11/09 Nota E. Giovannetti - AlgELab-09-10 - Lez.30 40 Riassumendo: Se q = 1, cioè a = bs : Consideriamo l'albero di ricorsione (cioè delle chiamate ricorsive): • Ogni chiamata, per n > 1, effettua a chiamate ricorsive: all'i-esimo livello dell'albero si hanno quindi ai nodi (chiamate ricorsive). • La dimensione dei sottoproblemi diminuisce di un fattore b ad ogni successivo livello: all'i-esimo livello la dimensione è q quindi n/bi. • Il lavoro compiuto per ogni sottoproblema di livello i è quindi (n/bi)s. • Il lavoro totale al livello i è pertanto ai(n/bi)s, che è = (a/bs)i ns. • Ponendo bk = n, cioè k = logbn, si raggiunge il caso base T(1) dopo k livelli, cioè l'altezza dell'albero di ricorsione è k. • Il lavoro totale è dato dalla somma di tutti i livelli, cioè per i che varia da 0 a k (= logbn): Quindi: come già visto nella slide 27. 26/11/09 E. Giovannetti - AlgELab-09-10 - Lez.30 41 26/11/09 E. Giovannetti - AlgELab-09-10 - Lez.30 42 7 Abbiamo dimostrato il teorema master o teorema fondamentale delle ricorrenze: Teorema fondamentale delle ricorrenze: enunciazione equivalente. Per una forma più generale del teorema (non necessaria nella maggior parte dei casi, e non richiesta nel nostro corso) si veda il libro di testo. Per una forma più generale del teorema (non necessaria nella maggior parte dei casi, e non richiesta nel nostro corso) si veda il libro di testo. 26/11/09 E. Giovannetti - AlgELab-09-10 - Lez.30 43 26/11/09 Ripasso/approfondimento del significato intuitivo Osserva: • il lavoro di scomposizione e ricomposizione del problema di partenza ha costo temporale ns; • il lavoro di scomposizione e ricomposizione di un problema del primo livello di ricorsione ha costo (n/b)s = ns/bs; • il lavoro di scomposizione e ricomposizione di un problema del secondo livello di ricorsione ha costo (n/b2)s = ns/(bs)2; • ... e così via. Quindi bs indica di quante volte si riduce, a ogni nuovo livello di sottoproblemi, il lavoro di scomposizione e ricomposizione all'interno di ciascun sottoproblema di quel livello. 26/11/09 E. Giovannetti - AlgELab-09-10 - Lez.30 45 • il lavoro di scomposizione e ricomposizione all'interno di ciascun problema si riduce di più volte di quante cresca il numero dei problemi stessi; • il llavoro di scomposizione i i d dell problema bl di partenza in i sottoproblemi, e di ricomposizione della soluzione, risulta dominante rispetto al lavoro per risolvere i sottoproblemi, cioè ai lavori di scomposizione e ricomposizione interni a tutti i sottoproblemi, e ai semplici lavori-base dei problemi di dimensione 1; • il tempo che conta, ai fini della complessità, è solo quello impiegato nella radice dell'albero di ricorsione. 26/11/09 E. Giovannetti - AlgELab-09-10 - Lez.30 46 Significato intuitivo (3) • il lavoro in ciascun problema si riduce esattamente di tante volte di quante cresce (per moltiplicazione) il numero dei problemi; • il tempo totale impiegato dalle divisioni e ricomposizioni in ciascun livello è quindi uguale al tempo occorrente per scomporre il problema di partenza e poi ricomporne la soluzione: tale tempo ns va quindi moltiplicato per il numero logb n dei livelli; • tutti i sottoproblemi, cioè tutti i nodi dell'albero di ricorsione, contribuiscono al tempo totale. E. Giovannetti - AlgELab-09-10 - Lez.30 44 Significato intuitivo (1) Significato intuitivo (2) 26/11/09 E. Giovannetti - AlgELab-09-10 - Lez.30 47 • il numero dei problemi cresce (moltiplicandosi) di più volte di quante si riduca il lavoro in ciascuno di essi; • ill tempo impiegato mp egato per risolvere r solvere tutt tutti i problemi-base problem base d di dimensione 1 risulta dominante rispetto ai tempi di scomposizione e ricomposizione (di tutti i livelli precedenti); il costo temporale totale è quindi dato semplicemente dal numero di tali problemi-base, cioè dal numero delle foglie dell'albero di ricorsione, che è ak, cioè , cioè ; • il tempo che conta, ai fini della complessità, è solo quello impiegato nelle foglie dell'albero di ricorsione. 26/11/09 E. Giovannetti - AlgELab-09-10 - Lez.30 48 8 Riassumendo ancora una volta: Ancora un'altra enunciazione equivalente ricorda la proprietà il costo prevalente è quello di divisione in sottoproblemi e ricomposizione della soluzione del problema di partenza. il costo prevalente è quello delle chiamate ricorsive; sia il costo delle chiamate ricorsive che il costo di divisione in sottoproblemi e ricomposizione della soluzione contribuiscono; il costo di scomposizione-ricomposizione e il costo delle chiamate ricorsive contribuiscono entrambi; il costo prevalente è quello delle chiamate ricorsive, cioè dei sottoproblemi, anzi dei sottoproblemi-base (foglie); 26/11/09 E. Giovannetti - AlgELab-09-10 - Lez.30 il costo prevalente è quello di scomposizione-ricomposizione del problema di partenza. 49 26/11/09 Esempi di applicazione del teorema a = 4, b = 2, s = 3 a < bs ad ogni livello si riduce di più di quanto si moltiplica: vince la base T(n) = = Θ(n3) a = 4, 4 b = 2, 2 s=2 a = bs ad ogni livello si riduce di quanto si moltiplica: contano tutti i livelli • T(n) T( ) = 4 T(n/2) T( /2) + 50 Esempi di applicazioni del teorema • T(n) = 4 T(n/2) + n3 Θ(ns) E. Giovannetti - AlgELab-09-10 - Lez.30 n2 • Prodotto di matrici, primo tentativo divide-et-impera: T(n) = 8 T(n/2) + cn2 (a = 8, b = 2, s = 2) È a > bs, cioè log2 8 = 3 > 2 quindi T(n) = Θ(nlogba) = Θ(n3) Non si ha nessun vantaggio rispetto all'algoritmo ingenuo ! T(n) = Θ(ns logbn) = Θ(n2 lg n) a = 4, b = 2, s = 1 a > bs ad ogni livello si moltiplica di più di quanto si riduce : vincono le foglie • T(n) = 4 T(n/2) + n T(n) = Θ(nlogba) = Θ(n2) 26/11/09 E. Giovannetti - AlgELab-09-10 - Lez.30 51 Esempi di applicazioni del teorema È a > bs, cioè log2 7 ≅ 2,81 > 2 quindi T(n) = Θ(n2,81) L'algoritmo è, per n grande, migliore dell'algoritmo banale che è di complessità O(n3); per n piccolo l'algoritmo banale può essere più veloce, a causa delle "grandi" costanti "n sc st " nell "nascoste" n ll'ordine rdin di grandezza. r nd zz Esistono algoritmi asintoticamente ancora più efficienti, ad es. O(n2,37), ma in realtà più lenti a causa di enormi costanti moltiplicative. • Ricerca binaria ricorsiva: T(n) = T(n/2) + c (a = 1, b = 2, s = 0) È a = bs (cioè log2 1 = 0); T(n) = ns logbn = n0 log n = log n E. Giovannetti - AlgELab-09-10 - Lez.30 E. Giovannetti - AlgELab-09-10 - Lez.30 52 Esempio di applicazione "estesa" del teorema • Moltiplicazione di matrici con il metodo di van Strassen: T(n) = 7 T(n/2) + cn2 (a = 7, b = 2, s = 2) 26/11/09 26/11/09 53 • Algoritmo heapify (costruzione dello heap dal basso): T(n) = 2T(n/2) + log2 n (a = 2, b = 2, s < ε) Ricorda (lez. 4): log n = O(nε), per ε positivo "piccolo a piacere". Quindi è a > bs, perché ad es. 2 > 21/2, quindi: T(n) = Θ(nlogba) = Θ((n)) 26/11/09 E. Giovannetti - AlgELab-09-10 - Lez.30 54 9 Esercizio: esempi di applicazione del teorema Si verifichi che, usando il teorema per l'analisi di algoritmi divide-et-impera già studiati (ad es. mergesort, quicksort), si ritrovano gli stessi risultati già ottenuti applicando il metodo di espansione iterativa direttamente. Ripasso altre equazioni di ricorrenza. • Attenzione: le equazioni di ricorrenza della forma: T(1) = d; T(n) = aT(n-b) + cns non sono della forma divide-et-impera a partiz. bilanciata ! Il teorema fondamentale non si applica ad esse ! • Esempi: • Hanoi: T(n) = 2T(n-1) + 1 ha soluzione T(n) = Θ(2n) • qsort worst: T(n) = T(n-1) + n ha soluzione T(n) = Θ(n2) • ... 26/11/09 E. Giovannetti - AlgELab-09-10 - Lez.30 55 Un altro algoritmo divide-et-impera: prodotto di interi di grandezza arbitraria (prodotto di polinomi) E. Giovannetti - AlgELab-09-10 - Lez.30 ha soluzione T(n) = Θ(n) E. Giovannetti - AlgELab-09-10 - Lez.30 56 Moltiplicazione di interi arbitrari • Un intero arbitrario non può essere rappresentato da un valore di un tipo avente lunghezza prefissata come int o long, ma deve essere rappresentato da una sequenza (array o lista) di cifre; a tal fine non è restrittivo assumere, nel ragionamento, g , che le cifre siano decimali (anche ( se poi p nelle realizzazioni si userà come base l'opportuna potenza di 2). • Le operazioni elementari somma e prodotto non sono più effettuabili in tempo costante. • Addizione: evidentemente richiede un tempo lineare nel numero di cifre (è l'algoritmo della scuola elementare !). • Qual è la complessità temporale dell'operazione di moltiplicazione ? 26/11/09 26/11/09 T(n) = T(n-1) + 1 57 Algoritmo della scuola elementare: richiede di moltiplicare ogni cifra di un numero per tutte le cifre dell'altro; se i due numeri hanno entrambi n cifre, il tempo richiesto è quindi Θ(n2) (algoritmo quadratico) Realizzazione. M = cn-1cn-2 ... c1c0 = cn-110n-1 + cn-210n-2 + ... + c110 + c0 N = dn-1dn-2 ... d1d0 = dn-110n-11 + dn-210n-22 + ... + d110 + d0 Il coefficiente pk di 10k nel prodotto è dato da: per trovare le cifre di M.N occorre poi fare le addizioni con i riporti (complessità lineare), ecc. Esiste un algoritmo migliore ? 26/11/09 Primo tentativo divide et impera E. Giovannetti - AlgELab-09-10 - Lez.30 58 Passo di ricorsione Base della ricorsione. La moltiplicazione di due numeri costituiti da una sola cifra può essere eseguita direttamente. Passo di ricorsione Cerchiamo di scomporre il problema in (quanti?) problemi di dim nsi n m dimensione metà. tà Osserviamo che, se M è un numero di n cifre, si ha: M = M1×10n/2 + M0 dove M1 sono le n/2 cifre pìù significative M0 sono le n/2 cifre meno significative. Esempio: 28753043 = 2875×104 + 3043 Allora: (vedi slide seguente) Se M = M1×10n/2 + M0 N = N1×10n/2 + N0 allora: MN = M1N1×10n + (M0N1 + M1N0 )×10n/2 + M0N0 Una moltiplicazione per 10k si ottiene semplicemente per scorrimento (shift) delle cifre, quindi in tempo k = O(n). Le addizioni richiedono un tempo lineare in n, cioè O(n). Vi sono però da fare 4 moltiplicazioni di numeri di n/2 cifre. cifre Il problema si scinde in 4 sottoproblemi di dimensione metà, più un tempo lineare di scomposizione e ricomposizione: a = 4, b = 2, s = 1: Non abbiamo guadagnato niente ! 26/11/09 E. Giovannetti - AlgELab-09-10 - Lez.30 59 26/11/09 E. Giovannetti - AlgELab-09-10 - Lez.30 60 10 Soluzione: ridurre il numero dei sottoproblemi MN = M1N1 + (M1N0 + M0N1 + M0 N 0 Ancora un po' di algebretta: (M1 + M0)(N1 + N0) = M1N1 + M0N0 + M1N0 + M0N1 quindi: M1N0 + M0N1 = (M1 + M0)(N1 + N0) – M1N1 – M0N0 Ma i prodotti M1N1 e M0N0 li dobbiamo comunque calcolare, quindi le moltiplicazioni si possono ridurre da 4 a 3: P 0 = M0 N 0 P 1 = M1 N 1 Q = (M1 + M0)(N1 + N0) ×10n E. Giovannetti - AlgELab-09-10 - Lez.30 a = 3, b = 2, s = 1 • Scomposizione e ricomposizione sono un po' più complicate, quindi i di richiedono i hi d un ttempo maggiore, i ma sempre li lineare. • Questo, però, permette di ridurre i sottoproblemi (cioè le chiamate ricorsive) da 4 a 3, e quindi un guadagno di complessità asintotica: Θ(n1.59) è asintoticamente meglio di Θ(n2) ! cioè per n sufficientemente grande il secondo algoritmo impiega meno tempo di quello ingenuo. MN = P1×10n + (Q – P1 – P0 )×10n/2 + P0 26/11/09 Ce l'abbiamo fatta ! )×10n/2 61 Appendice 1 Dimostrazione del teorema master per mezzo di sviluppo puramente algebrico. 26/11/09 E. Giovannetti - AlgELab-09-10 - Lez.30 62 Poniamo, per semplicità: • Attenzione: il calcolo riportato nelle slides seguenti, benché a prima vista possa sembrare complicato, non è più difficile dello sviluppo delle equazioni del mergesort o quicksort. Anzi, essendo più meccanico del ragionamento informale riportato nei lucidi precedenti, per qualcuno può risultare più facile. 26/11/09 E. Giovannetti - AlgELab-09-10 - Lez.30 63 26/11/09 E. Giovannetti - AlgELab-09-10 - Lez.30 64 Riassumendo: assumiamo n = bk quindi • Al livello i: ai sottoproblemi di dimensione • Costo di ciascun sottoproblema di livello i: • Costo totale del livello i: • k+1 livelli (da 0 a k), quindi il costo totale è: successione geometrica di ragione a/bs Si hanno tre casi, a seconda che a/bs sia <, >, = 1 26/11/09 E. Giovannetti - AlgELab-09-10 - Lez.30 65 26/11/09 E. Giovannetti - AlgELab-09-10 - Lez.30 66 11 Infine, in breve: Dimostrazione rigorosa dei due casi con a ≠ bs. successione geometrica di ragione a/bs Per semplificare la scrittura poniamo q = a/bs. Allora: • a/bs < 1: progressione decrescente (vedi slides seguenti), è dominante il primo termine (cioè per i = 0): a < bs Æ • a/b /bs = 1: tutti i k+1 termini della somma sono uguali a ns: a = bs Æ • a/bs > 1: progressione crescente (vedi slides seguenti), è dominante l'ultimo termine: a > bs Æ 26/11/09 E. Giovannetti - AlgELab-09-10 - Lez.30 è l'ultimo termine della successione c.v.d. 67 26/11/09 Appendice 2 Ripasso proprietà cambio di base dei logaritmi E. Giovannetti - AlgELab-09-10 - Lez.30 68 Appendice 3 (NON richiesta all'esame !) Teorema fondamentale delle ricorrenze: dimostrazione con costanti c e d generiche. segue g approssimativamente pp m m il testo Bertossi, Algoritmi e strutture dati, UTET 2000 (non richiesto per l'esame: il calcolo è fondamentalmente lo stesso di quello che abbiamo visto con c = 1 e d = 1; la presenza esplicita delle due costanti rende però un po' meno leggibili le formule, pur non aggiungendo quasi nulla di nuovo alla comprensione del teorema) 26/11/09 E. Giovannetti - AlgELab-09-10 - Lez.30 69 26/11/09 E. Giovannetti - AlgELab-09-10 - Lez.30 70 71 26/11/09 E. Giovannetti - AlgELab-09-10 - Lez.30 72 Poniamo, per semplicità: 26/11/09 E. Giovannetti - AlgELab-09-10 - Lez.30 12 Abbiamo dunque ottenuto: Si hanno i tre casi: • γ > s: ricordando che è b > 1, si ha q > 1; • γ = s: si ha q = 1; • γ < s: ricordando che è b > 1, si ha q < 1. Nei casi 1 e 3 si ha: q ≠ 1 e quindi: 26/11/09 E. Giovannetti - AlgELab-09-10 - Lez.30 73 26/11/09 E. Giovannetti - AlgELab-09-10 - Lez.30 74 13