Divide-and-Conquer Chapter 5 Divide and Conquer Divide-and-conquer. Dividere il problema in diverse parti. Divide et impera. Veni, vidi, vici. - Giulio Cesare Risolvere ogni parte ricorsivamente. Combinare le soluzioni dei sottoproblemi in soluzioni globali. Uso più comune. Dividere il problema di tagli n in due parti uguali di taglia n/2. Risolvere ogni parte ricorsivamente. Combinare le soluzioni dei sottoproblemi in soluzioni globali in tempo lineare. Efficienza. Algoritmo naïve: O(n 2 ). Divide-and-conquer: O(n log n). 1 2 Divide and Conquer Algoritmi che vedremo: Mergesort Quicksort Counting Inversions Closest Pair of Points Integer Multiplication Matrix Multiplication 5.1 Mergesort Esercizi: Potenze di un numero Numeri di Fibonacci Massima Sottosequenza Massimi in 2-D Defective Chessboards 3
Ordinamento Mergesort Ordinamento. Dati n elementi, disporli in ordine crescente. Applicazioni ovvie: List files in a directory. Organize an MP3 library. List names in a phone book. Display Google PageRank results. Problemi più semplici dopo ordinamento. Find the median. Find the closest pair. Binary search in a database. Identify statistical outliers. Find duplicates in a mailing list. Applicazioni non-ovvie: Data compression. Computer graphics. Interval scheduling. Computational biology. Minimum spanning tree. Supply chain management. Simulate a system of particles. Book recommendations on Amazon. Load balancing on a parallel computer.... Mergesort. Dividere array in due metà. Ricorsivamente ordina ogni metà. Merge due metà per ottenere tutta la sequenza ordinata. Jon von Neumann (1945) A L G O R I T H M S A L G O R I T H M S A G L O R H I M S T A G H I L M O R S T 5 6 MergeSort (esempio) - 1 MergeSort (esempio) - 2 7 8
MergeSort (esempio) - 3 MergeSort (esempio) - 4 9 10 MergeSort (esempio) - 5 MergeSort (esempio) - 6 11 12
MergeSort (esempio) - 7 MergeSort (esempio) - 8 13 14 MergeSort (esempio) - 9 MergeSort (esempio) - 10 15 16
MergeSort (esempio) - 11 MergeSort (esempio) - 12 17 18 MergeSort (esempio) - 13 MergeSort (esempio) - 14 19 20
MergeSort (esempio) - 15 MergeSort (esempio) - 16 21 22 MergeSort (esempio) - 17 MergeSort (esempio) - 18 23 24
MergeSort (esempio) - 19 MergeSort (esempio) - 20 25 26 MergeSort (esempio) - 21 MergeSort (esempio) - 22 27 28
Mergesort Mergesort Mergesort. Dividere array in due metà. Ricorsivamente ordina ogni metà. Merge due metà per ottenere tutta la sequenza ordinata. Mergesort. Dividere array in due metà. Ricorsivamente ordina ogni metà. Merge due metà per ottenere tutta la sequenza ordinata. Jon von Neumann (1945) Jon von Neumann (1945) 29 30 Merge Merge Merging. Combina due liste ordinate in un unica lista ordinata. Come effettuare il merge efficientemente? Uso di un array temporaneo. Merge. Mantenere traccia dellelemento più piccolo in ogni metà ordinata. Inserire il più piccolo dei due elementi in un. Ripetere fino a terminare gli elementi nelle due metà. A G L O R H I M S T A G H I smallest A G L O R smallest H I M S T A 31 32
Merge Merge Merge. Mantenere traccia dellelemento più piccolo in ogni metà ordinata. Inserire il più piccolo dei due elementi in un. Ripetere fino a terminare gli elementi nelle due metà. Merge. Mantenere traccia dellelemento più piccolo in ogni metà ordinata. Inserire il più piccolo dei due elementi in un. Ripetere fino a terminare gli elementi nelle due metà. smallest smallest smallest smallest A G L O R H I M S T A G L O R H I M S T A G A G H 33 34 Merge Merge Merge. Mantenere traccia dellelemento più piccolo in ogni metà ordinata. Inserire il più piccolo dei due elementi in un. Ripetere fino a terminare gli elementi nelle due metà. Merge. Mantenere traccia dellelemento più piccolo in ogni metà ordinata. Inserire il più piccolo dei due elementi in un. Ripetere fino a terminare gli elementi nelle due metà. smallest smallest smallest smallest A G L O R H I M S T A G L O R H I M S T A G H I A G H I L 35 36
Merge Merge Merge. Mantenere traccia dellelemento più piccolo in ogni metà ordinata. Inserire il più piccolo dei due elementi in un. Ripetere fino a terminare gli elementi nelle due metà. Merge. Mantenere traccia dellelemento più piccolo in ogni metà ordinata. Inserire il più piccolo dei due elementi in un. Ripetere fino a terminare gli elementi nelle due metà. smallest smallest smallest smallest A G L O R H I M S T A G L O R H I M S T A G H I L M A G H I L M O 37 38 Merge Merge Merge. Mantenere traccia dellelemento più piccolo in ogni metà ordinata. Inserire il più piccolo dei due elementi in un. Ripetere fino a terminare gli elementi nelle due metà. Merge. Mantenere traccia dellelemento più piccolo in ogni metà ordinata. Inserire il più piccolo dei due elementi in un. Ripetere fino a terminare gli elementi nelle due metà. smallest smallest prima metà terminata smallest A G L O R H I M S T A G L O R H I M S T A G H I L M O R A G H I L M O R S 39 40
Merge Merge Merge. Mantenere traccia dellelemento più piccolo in ogni metà ordinata. Inserire il più piccolo dei due elementi in un. Ripetere fino a terminare gli elementi nelle due metà. Merge. Mantenere traccia dellelemento più piccolo in ogni metà ordinata. Inserire il più piccolo dei due elementi in un. Ripetere fino a terminare gli elementi nelle due metà. prima metà terminata smallest prima metà terminata seconda metà terminata A G L O R H I M S T A G L O R H I M S T A G H I L M O R S T A G H I L M O R S T 41 42 Merge Merging. Combina due liste ordinate in un unica lista ordinata. Come effettuare il merge efficientemente? Numero lineare di confronti. Uso di un array temporaneo. A G L O R H I M S T Mergesort. Dividere array in due metà. Mergesort Ricorsivamente ordina ogni metà. Merge due metà per ottenere tutta la sequenza ordinata. Definizione. T(n) = numero di confronti mergesort per input di n elementi. A L G O R I T H M S Jon von Neumann (1945) A G H I A L G O R I T H M S dividi O(1) A G L O R H I M S T ordina 2T(n/2) A G H I L M O R S T merge O(n) 43 44
Una utile relazione di ricorrenza Prova con Albero di Ricorsione Definizione. T(n) = numero di confronti mergesort per input n elementi. Ricorrenza del Mergesort. T(n) ' 0 se n =1 ) ( T ( # n /2$ ) + T ( % n /2& ) + cn altrimenti * ) risolvi parte sinistra risolvi parte destra merge T(n) ' ) ( * ) 0 se n =1 T ( # n /2$ ) + T ( % n /2& ) + cn altrimenti risolvi parte sinistra risolvi parte destra merge T(n) cn Soluzione. T(n) = O(n log 2 n). T(n/2) T(n/2) cn Varie prove. Descriviamo vari modi per risolvere questa ricorrenza. Iniziamente assumiamo che n è una potenza di 2 e sostituiamo con =. T(n/4) c n/2 T(n/4) T(n/4) c n/2 T(n/4) 45 46 Prova con Albero di Ricorsione Prova con Albero di Ricorsione T(n) ' 0 se n =1 ) ( T ( # n /2$ ) + T ( % n /2& ) + cn altrimenti * ) risolvi parte sinistra risolvi parte destra merge T(n) ' 0 se n =1 ) ( T ( # n /2$ ) + T ( % n /2& ) + cn altrimenti * ) risolvi parte sinistra risolvi parte destra merge cn cn cn cn c n/2 c n/2 2 c(n/2) c n/2 c n/2 2 c(n/2) c n/4 c n/4 c n/4 c n/4 h+1 4 c(n/4)... c n/4 c n/4 c n/4 c n/4 h+1 4 c(n/4)... c n / 2 k 2 k c(n / 2 k ) c n / 2 k 2 k c(n / 2 k )...... c 2 c 2 c 2 c 2 c 2 c 2 c 2 c 2 n/2 c(2) c 2 c 2 c 2 c 2 c 2 c 2 c 2 c 2 n/2 c(2) Altezza albero h? cn (h+1) Altezza albero h? n / 2 h = 2 cioè h = log 2 n - 1 cn (h+1) 47 48
Prova con metodo iterativo Prova con sequenza telescopica Claim. T(n) = c n log 2 n. (assumiamo n potenza di 2) Claim. T(n) = c n log 2 n. (assumiamo n potenza di 2) T(n) ' 0 se n =1 ) ( T ( # n /2$ ) + T ( % n /2& ) + cn altrimenti * ) risolvi parte sinistra risolvi parte destra merge T(n) ' 0 se n =1 ) ( T ( # n /2$ ) + T ( % n /2& ) + cn altrimenti * ) risolvi parte sinistra risolvi parte destra merge T(n) = cn + 2T(n/2) = cn + 2(cn/2 + 2T(n/4)) = cn + cn + 4T(n/4) = cn + cn + 4(n/4 + 2T(n/8)) = cn + cn + cn + 8T(n/8) = = icn + 2 i T(n/2 i ) = kcn + 2 k T(1) = c n lg n + n T(1) = c n log 2 n n = 2 k lg n = lg (2 k ) lg n = k lg 2 lg n = k Prova. Per n > 1: T (n) n = = = = 2T (n /2) n T (n /2) n /2 T (n / 4) n / 4 T (n /n) n /n = clog 2 n + c + c + c + c + c ++ c log 2 n T (n /2) n /2 = T (n / 4) n / 4 + c 49 50 Prova per induzione Analisi della ricorrenza del Mergesort Claim. T(n) = n log 2 n. (assumiamo n potenza di 2) Claim. T(n) c n "log n#. (logaritmo in base 2, cioè log = log 2 ) T(n) ' 0 se n =1 ) ( T ( # n /2$ ) + T ( % n /2& ) + cn altrimenti * ) risolvi parte sinistra risolvi parte destra merge T(n) ' 0 se n =1 ) ( T ( # n /2$ ) + T ( % n /2& ) + cn altrimenti * ) risolvi parte sinistra risolvi parte destra merge Prova. (per induzione su n) Caso base: n = 1. Ipotesi induttiva: T(n) = c n log 2 n. Obiettivo: mostrare che T(2n) = c 2n log 2 (2n). T (2n) = 2T (n) + c2n = c2n log 2 n + c2n ( ) + c2n = c2n log 2 (2n) 1 = c2n log 2 (2n) Prova. (per induzione su n) Caso base: n = 1. Definiamo n 1 = $n / 2%, n 2 = "n / 2#. Passo induzione: assumiamo che sia vero per 1, 2,..., n 1. T (n) T (n 1 ) + T (n 2 ) + cn cn 1 # logn 1 $ + cn 2 # log n 2 $ + cn cn 1 # logn 2 $ + cn 2 # log n 2 $ + cn = cn # log n 2 $ + cn cn( # logn$ 1 ) + cn = cn# log n$ n 2 =!" n / 2#$! " 2!" logn #$ / 2 # $ = 2 logn!" #$ / 2 logn 2!" logn#$ 1 51 52
Risoluzione ricorrenze della forma dove a 1, b > 1, f(n) > 0 Master s method! T(n) = at n $ # & + f(n) " b% Risoluzione ricorrenze della forma dove a 1, b > 1, f(n) > 0 Master s method! T(n) = at n $ # & + f(n) " b% Caso 1: se f(n) = O(n log b a -ε ) per qualche ε > 0, allora T(n) = Θ(n log b a ) Caso 2: se f(n) = Θ(n log b a ), allora T(n) = Θ(n log b a lg n) Caso 3: se f(n) = Ω(n log b a +ε ) per qualche ε > 0, e se af(n/b) cf(n) per qualche c < 1 e tutti gli n sufficientemente grandi, allora T(n) = Θ(f(n)) 53 54 Master s method Risoluzione ricorrenze della forma dove a 1, b > 1, f(n) > 0! T(n) = at n $ # & + f(n) " b% 5.3 Counting Inversions Caso 1: se f(n) = O(n log b a -ε ) per qualche ε > 0, allora T(n) = Θ(n log b a ) Caso 2: se f(n) = Θ(n log b a ), allora T(n) = Θ(n log b a lg n) Caso 3: se f(n) = Ω(n log b a +ε ) per qualche ε > 0, e se af(n/b) cf(n) per qualche c < 1 e tutti gli n sufficientemente grandi, allora T(n) = Θ(f(n)) Esempio: T(n) = 2T(n/2) + n a = 2, b = 2 Confrontiamo n log 2 2 con f(n) = n Abbiamo f(n) = Θ(n), quindi Caso 2 T(n) = Θ(n lg n) 55
Conteggio Inversioni Applicazioni Sito musica cerca di fare un match delle preferenze musicali di utenti. Ognuno classifica n brani. Sito musica consulta il data base per cercare liste di preferenze simili di utenti. Metrica di similarità: numero di inversioni tra due liste di preferenza. Primo rank: 1, 2,, n. Secondo rank: a 1, a 2,, a n. Brano i and j invertiti se i < j, ma a i > a j. Brani io tu A B C D E 1 2 3 4 5 1 3 4 2 5 Inversioni 3-2, 4-2 Applicazioni. Voting theory. Collaborative filtering. Measuring the "sortedness" of an array. Sensitivity analysis of Google's ranking function. Rank aggregation for meta-searching on the Web. Nonparametric statistics (e.g., Kendall's Tau distance). Algoritmo Brute force : controlla tutte le Θ(n 2 ) coppie i e j. 57 58 Conteggio Inversioni Conteggio Inversioni: Divide-and-Conquer Divide-and-conquer. 1 5 4 8 10 2 6 9 12 11 3 7 59 60
Conteggio Inversioni: Divide-and-Conquer Conteggio Inversioni: Divide-and-Conquer Divide-and-conquer. Divide: dividi lista in due parti. Divide-and-conquer. Divide: dividi lista in due parti. Conquer: conta ricorsivamente le inversioni in ogni parte. 1 5 4 8 10 2 6 9 12 11 3 7 Divide: O(1). 1 5 4 8 10 2 6 9 12 11 3 7 Divide: O(1). 1 5 4 8 10 2 6 9 12 11 3 7 1 5 4 8 10 2 6 9 12 11 3 7 Conquer: 2 T(n / 2) 5 inversioni blu-blu 8 inversioni verde-verde 5-4, 5-2, 4-2, 8-2, 10-2 6-3, 9-3, 9-7, 12-3, 12-7, 12-11, 11-3, 11-7 61 62 Conteggio Inversioni: Divide-and-Conquer Conteggio Inversioni: Combine Divide-and-conquer. Divide: dividi lista in due parti. Conquer: conta ricorsivamente le inversioni in ogni parte. Combine: conta le inversioni dove a i e a j sono in parti diverse, e restituisci la somma dele tre quantità. Combine: conteggio inversioni blu-verde Assumiamo che ogni metà è ordinata. Contiamo le inversioni dove a i e a j sono in Merge due parti ordinate in una sola sequenza ordinata. per mantenere linvariante dell ordinamento 1 5 4 8 10 2 6 9 12 11 3 7 Divide: O(1). 1 5 4 8 10 2 6 9 12 11 3 7 5 inversioni blu-blu 8 inversioni verde-verde Conquer: 2 T(n / 2) 9 inversioni blu-verde 5-3, 4-3, 8-6, 8-3, 8-7, 10-6, 10-9, 10-3, 10-7 Combine:??? Total = 5 + 8 + 9 = 22. 63 64
Merge and Count Merge and Count Passo di merge and count. Date due parti ordinate, contiamo le inversioni dove a i e a j sono in Combiniamo due parti ordinate in una sola sequenza ordinata. Passo di merge and count. Date due parti ordinate, contiamo le inversioni dove a i e a j sono in Combiniamo due parti ordinate in una sola sequenza ordinata. i = 6 i = 6 6 2 Totale: Totale: 6 65 66 Merge and Count Merge and Count Passo di merge and count. Date due parti ordinate, contiamo le inversioni dove a i e a j sono in Combiniamo due parti ordinate in una sola sequenza ordinata. Passo di merge and count. Date due parti ordinate, contiamo le inversioni dove a i e a j sono in Combiniamo due parti ordinate in una sola sequenza ordinata. i = 6 i = 6 6 6 2 2 3 Totale: 6 Totale: 6 67 68
Merge and Count Merge and Count Passo di merge and count. Date due parti ordinate, contiamo le inversioni dove a i e a j sono in Combiniamo due parti ordinate in una sola sequenza ordinata. Passo di merge and count. Date due parti ordinate, contiamo le inversioni dove a i e a j sono in Combiniamo due parti ordinate in una sola sequenza ordinata. i = 5 i = 5 6 6 2 3 2 3 7 Totale: 6 Totale: 6 69 70 Merge and Count Merge and Count Passo di merge and count. Date due parti ordinate, contiamo le inversioni dove a i e a j sono in Combiniamo due parti ordinate in una sola sequenza ordinata. Passo di merge and count. Date due parti ordinate, contiamo le inversioni dove a i e a j sono in Combiniamo due parti ordinate in una sola sequenza ordinata. i = 4 i = 4 6 6 2 3 7 2 3 7 10 Totale: 6 Totale: 6 71 72
Merge and Count Merge and Count Passo di merge and count. Date due parti ordinate, contiamo le inversioni dove a i e a j sono in Combiniamo due parti ordinate in una sola sequenza ordinata. Passo di merge and count. Date due parti ordinate, contiamo le inversioni dove a i e a j sono in Combiniamo due parti ordinate in una sola sequenza ordinata. i = 3 i = 3 6 6 3 2 3 7 10 2 3 7 10 11 Totale: 6 Totale: 6 + 3 73 74 Merge and Count Merge and Count Passo di merge and count. Date due parti ordinate, contiamo le inversioni dove a i e a j sono in Combiniamo due parti ordinate in una sola sequenza ordinata. Passo di merge and count. Date due parti ordinate, contiamo le inversioni dove a i e a j sono in Combiniamo due parti ordinate in una sola sequenza ordinata. i = 3 i = 3 6 3 6 3 2 3 7 10 11 2 3 7 10 11 14 Totale: 6 + 3 Totale: 6 + 3 75 76
Merge and Count Merge and Count Passo di merge and count. Date due parti ordinate, contiamo le inversioni dove a i e a j sono in Combiniamo due parti ordinate in una sola sequenza ordinata. Passo di merge and count. Date due parti ordinate, contiamo le inversioni dove a i e a j sono in Combiniamo due parti ordinate in una sola sequenza ordinata. i = 2 i = 2 6 3 6 3 2 2 3 7 10 11 14 2 3 7 10 11 14 16 Totale: 6 + 3 Totale: 6 + 3 + 2 77 78 Merge and Count Merge and Count Passo di merge and count. Date due parti ordinate, contiamo le inversioni dove a i e a j sono in Combiniamo due parti ordinate in una sola sequenza ordinata. Passo di merge and count. Date due parti ordinate, contiamo le inversioni dove a i e a j sono in Combiniamo due parti ordinate in una sola sequenza ordinata. i = 2 i = 2 6 3 2 6 3 2 2 2 3 7 10 11 14 16 2 3 7 10 11 14 16 17 Totale: 6 + 3 + 2 Totale: 6 + 3 + 2 + 2 79 80
Merge and Count Merge and Count Passo di merge and count. Date due parti ordinate, contiamo le inversioni dove a i e a j sono in Combiniamo due parti ordinate in una sola sequenza ordinata. Passo di merge and count. Date due parti ordinate, contiamo le inversioni dove a i e a j sono in Combiniamo due parti ordinate in una sola sequenza ordinata. i = 2 i = 2 6 3 2 2 6 3 2 2 2 3 7 10 11 14 16 17 2 3 7 10 11 14 16 17 18 Totale: 6 + 3 + 2 + 2 Totale: 6 + 3 + 2 + 2 81 82 Merge and Count Merge and Count Passo di merge and count. Date due parti ordinate, contiamo le inversioni dove a i e a j sono in Combiniamo due parti ordinate in una sola sequenza ordinata. Passo di merge and count. Date due parti ordinate, contiamo le inversioni dove a i e a j sono in Combiniamo due parti ordinate in una sola sequenza ordinata. i = 1 i = 1 6 3 2 2 6 3 2 2 2 3 7 10 11 14 16 17 18 2 3 7 10 11 14 16 17 18 19 Totale: 6 + 3 + 2 + 2 Totale: 6 + 3 + 2 + 2 83 84
Merge and Count Merge and Count Passo di merge and count. Date due parti ordinate, contiamo le inversioni dove a i e a j sono in Combiniamo due parti ordinate in una sola sequenza ordinata. Passo di merge and count. Date due parti ordinate, contiamo le inversioni dove a i e a j sono in Combiniamo due parti ordinate in una sola sequenza ordinata. prima metà terminata i = 0 i = 0 6 3 2 2 6 3 2 2 0 2 3 7 10 11 14 16 17 18 19 2 3 7 10 11 14 16 17 18 19 23 Totale: 6 + 3 + 2 + 2 Totale: 6 + 3 + 2 + 2 + 0 85 86 Merge and Count Merge and Count Passo di merge and count. Date due parti ordinate, contiamo le inversioni dove a i e a j sono in Combiniamo due parti ordinate in una sola sequenza ordinata. Passo di merge and count. Date due parti ordinate, contiamo le inversioni dove a i e a j sono in Combiniamo due parti ordinate in una sola sequenza ordinata. i = 0 i = 0 6 3 2 2 0 6 3 2 2 0 0 2 3 7 10 11 14 16 17 18 19 23 2 3 7 10 11 14 16 17 18 19 23 25 Totale: 6 + 3 + 2 + 2 + 0 Totale: 6 + 3 + 2 + 2 + 0 + 0 87 88
Merge and Count Conteggio Inversioni: Combine Passo di merge and count. Date due parti ordinate, contiamo le inversioni dove a i e a j sono in Combiniamo due parti ordinate in una sola sequenza ordinata. Combine: conteggio inversioni blu-verde Assumiamo che ogni metà è ordinata. Contiamo le inversioni dove a i e a j sono in Merge due parti ordinate in una sola sequenza ordinata. per mantenere l invariante dellordinamento i = 0 6 3 2 2 0 0 6 3 2 2 0 0 13 inversioni blu-verde: 6 + 3 + 2 + 2 + 0 + 0 2 3 7 10 11 14 16 17 18 19 23 25 Totale: 6 + 3 + 2 + 2 + 0 + 0 = 13 89 90 Conteggio Inversioni: Combine Conteggio Inversioni Combine: conteggio inversioni blu-verde Assumiamo che ogni metà è ordinata. Contiamo le inversioni dove a i e a j sono in Merge due parti ordinate in una sola sequenza ordinata. Algorithm 5.1, page 224 per mantenere linvariante dellordinamento 6 3 2 2 0 0 13 inversioni blu-verde: 6 + 3 + 2 + 2 + 0 + 0 Conteggio: O(n) 2 3 7 10 11 14 16 17 18 19 23 25 Merge: O(n) T(n) T( # n/2$ ) + T( % n/2& ) + O(n) T(n) = O(nlog n) 91 92
Conteggio Inversioni: Implementation Pre-condizione. [Merge-and-Count] A e B sono ordinati. Post-condizione. [Sort-and-Count] L è ordinato. 5.4 Closest Pair of Points Sort-and-Count(L) { if lista L ha un solo elemento return 0 e la lista L Divide la lista in due metà A e B (r A, A) Sort-and-Count(A) (r B, B) Sort-and-Count(B) (r B, L) Merge-and-Count(A, B) } return r = r A + r B + r e la lista ordinata L 93 Coppia di punti più vicini Coppia di punti più vicini Coppia più vicina. Dati n punti nel piano, trovare una coppia con la più piccola distanza euclidea tra loro. Primitiva geometrica fondamentale. Grafica, computer vision, sistemi informativi geografici, modellazione molecolare, controllo traffico aereo. Brute force. Controllare tutte le coppie di punti p e q. Complessità Θ(n 2 ). Coppia più vicina. Dati n punti nel piano, trovare una coppia con la più piccola distanza euclidea tra loro. Primitiva geometrica fondamentale. Grafica, computer vision, sistemi informativi geografici, modellazione molecolare, controllo traffico aereo. Brute force. Controllare tutte le coppie di punti p e q. Complessità Θ(n 2 ). Versione 1-D. Facile se i punti sono su una linea, O(n log n). Come? 95 96
Coppia di punti più vicini Coppia di punti più vicini Coppia più vicina. Dati n punti nel piano, trovare una coppia con la più piccola distanza euclidea tra loro. Coppia più vicina. Dati n punti nel piano, trovare una coppia con la più piccola distanza euclidea tra loro. Primitiva geometrica fondamentale. Grafica, computer vision, sistemi informativi geografici, modellazione molecolare, controllo traffico aereo. Primitiva geometrica fondamentale. Grafica, computer vision, sistemi informativi geografici, modellazione molecolare, controllo traffico aereo. Brute force. Controllare tutte le coppie di punti p e q. Complessità Θ(n 2 ). Brute force. Controllare tutte le coppie di punti p e q. Complessità Θ(n 2 ). Versione 1-D. Facile se i punti sono su una linea, O(n log n). Come? 1. Ordinamento 2. Minimo tra tutte le distanze tra punti successivi Esempio Input: 5, 20, 10, 7, 2, 13 Ordinamento: 2, 5, 7, 10, 13, 20 Minimo tra tutte le distanze tra ogni punto ed il successivo: min {3, 2, 3, 3, 7} = 2 Versione 1-D. Facile se i punti sono su una linea, O(n log n). Assunzione. Punti con diverse coordinate x. per semplificare la presentazione. Altrimenti rotazione oppure estendere algoritmo Problema considerato da M. I. Shamos e D. Hoey, inizio anni 70. Lalgoritmo O(n log n) che vedremo è essenzialmente la loro soluzione. 97 98 Coppia di punti più vicini: Primo tentativo Coppia di punti più vicini: Primo tentativo Divide. Dividiamo la regione in 4 quadranti. Divide. Dividiamo la regione in 4 quadranti Ostacolo. Impossibile assicurare n/4 punti in ogni parte. L L 99 100
Coppia di punti più vicini Coppia di punti più vicini Algoritmo. Divide: disegnare linea verticale L cosi che ci sono circa n/2 punti in ogni parte. Algoritmo. Divide: disegnare linea verticale L cosi che ci sono circa n/2 punti in ogni parte. Conquer: trovare ricorsivamente la coppia più vicina in ogni parte. L L 21 12 101 102 Coppia di punti più vicini Coppia di punti più vicini Algoritmo. Divide: disegnare linea verticale L cosi che ci sono circa n/2 punti in ogni parte. Conquer: trovare ricorsivamente la coppia più vicina in ogni parte. Combine: trovare la coppia più vicina con un punto in ogni parte. Restituisci la migliore delle 3 soluzioni. L Algoritmo. Divide: disegnare linea verticale L cosi che ci sono circa n/2 punti in ogni parte. Conquer: trovare ricorsivamente la coppia più vicina in ogni parte. Combine: trovare la coppia più vicina con un punto in ogni parte. Restituisci la migliore delle 3 soluzioni. L sembra Θ(n 2 ) 8 21 8 21 12 12 103 104
Coppia di punti più vicini Coppia di punti più vicini Trovare la coppia più vicina con un punto in ogni parte, assumendo che la distanza sia < δ. Trovare la coppia più vicina con un punto in ogni parte, assumendo che la distanza sia < δ. Observazione: è inutile considerare punti oltre distanza δ da L. L L 21 21 12 δ = min(12, 21) 12 δ = min(12, 21) 105 δ 106 Coppia di punti più vicini Coppia di punti più vicini Trovare la coppia più vicina con un punto in ogni parte, assumendo che la distanza sia < δ. Observazione: è inutile considerare punti oltre distanza δ da L. Ordinare punti nella striscia 2δ per coordinata y. Trovare la coppia più vicina con un punto in ogni parte, assumendo che la distanza sia < δ. Observazione: è inutile considerare punti oltre distanza δ da L. Ordinare punti nella striscia 2δ per coordinata y. Considerare solo i punti entro 11 posizioni nella lista ordinata! L L 7 7 6 6 4 5 21 4 5 21 12 3 δ = min(12, 21) 12 3 δ = min(12, 21) 2 2 1 1 δ 107 δ 108
Coppia di punti più vicini Coppia di punti più vicini Definizione. Sia s i il punto nella striscia 2δ, con la i-esima più piccola coordinata y. Definizione. Sia s i il punto nella striscia 2δ, con la i-esima più piccola coordinata y. Claim. Se i j 12, allora la distanza tra s i ed s j è almeno δ. 2 righe 29 31 39 30 j ½δ ½δ Claim. Se i j 12, allora la distanza tra s i ed s j è almeno δ. Prova. Non ci sono due punti nello stesso quadrato 1 ½δ-per-½δ (distanza max ). 2 δ 2 < δ i 27 28 ½δ 26 25 δ δ 109 110 Coppia di punti più vicini Coppia di punti più vicini Definizione. Sia s i il punto nella striscia 2δ, con la i-esima più piccola coordinata y. Definizione. Sia s i il punto nella striscia 2δ, con la i-esima più piccola coordinata y. Claim. Se i j 12, allora la distanza tra s i ed s j è almeno δ. Prova. Non ci sono due punti nello stesso quadrato 1 ½δ-per-½δ (distanza max ). 2 δ 2 < δ Due punti con almeno due righe tra loro 2 righe hanno distanza 2(½δ). Se vi è al massimo una riga tra loro, i allora i j 11. 39 36 33 27 35 32 28 40 37 34 29 38 31 30 j ½δ ½δ ½δ Claim. Se i j 12, allora la distanza tra s i ed s j è almeno δ. Prova. Non ci sono due punti nello stesso quadrato 1 ½δ-per-½δ (distanza max ). 2 δ 2 < δ Due punti con almeno due righe tra loro 2 righe hanno distanza 2(½δ). Se vi è al massimo una riga tra loro, i allora i j 11. 39 36 33 27 35 32 28 40 37 34 29 38 31 30 j ½δ ½δ ½δ 26 δ 25 δ 111 Nota. Il valore della costante non è molto importante. Claim ancora vero se sostituiamo 11 con 6. L esempio della figura non può accadere Sul testo troviamo 15 al posto di 11. 26 δ 25 δ 112
Coppia di punti più vicini: algoritmo Coppia di punti più vicini: complessità algoritmo Indichiamo con T(n) la complessità dellalgoritmo per n punti Closest-Pair(p 1,, p n ) { Calcolare linea di separazione L tale che divide i punti in due parti uguali. δ 1 = Closest-Pair(metà sinistra) δ 2 = Closest-Pair(metà destra) δ = min(δ 1, δ 2 ) Cancellare tutti punti con distanza >δ da L Ordinare i punti rimanenti per coordinata y. Scansione punti ordinati rispetto ad y e confrontare distanza tra ogni punto ed i successivi 11 punti. Se una distanza è <δ, aggiornare δ. Closest-Pair(p 1,, p n ) { Calcolare linea di separazione L tale che divide i punti in due parti uguali. δ 1 = Closest-Pair(metà sinistra) δ 2 = Closest-Pair(metà destra) δ = min(δ 1, δ 2 ) Cancellare tutti punti con distanza >δ da L Ordinare i punti rimanenti per coordinata y. Scansione punti ordinati rispetto ad y e confrontare distanza tra ogni punto ed i successivi 11 punti. Se una distanza è <δ, aggiornare δ. O(n log n) 2T(n / 2) O(n) O(n log n) O(n) } return δ. } return δ. 113 114 Coppia di punti più vicini: complessità algoritmo Prova con Albero di Ricorsione Complessità algoritmo. T(n) = 2T ( n /2) + O(n log n) T(n) = O(n log 2 n) T(n) 2T( n/2) + O(n log n) T(n) = O(n log 2 n) T(n) c n log n T(n/2) T(n/2) c n log n c (n/2) log (n/2) c (n/2) log (n/2) T(n/4) T(n/4) T(n/4) T(n/4) 115 116
Prova con Albero di Ricorsione Prova con Albero di Ricorsione T(n) 2T( n/2) + O(n log n) T(n) = O(n log 2 n) T(n) 2T( n/2) + O(n log n) T(n) = O(n log 2 n) c n log n c n log n c n log n c n log n c (n/2) log (n/2) c (n/2) log (n/2) 2 c (n/2) log (n/2) c (n/2) log (n/2) c (n/2) log (n/2) 2 c (n/2) log (n/2) c (n/4) log (n/4) c (n/4) log (n/4) c (n/4) log (n/4) c (n/4) log (n/4) h+1 4 c (n/4) log (n/4) c (n/4) log (n/4) c (n/4) log (n/4) c (n/4) log (n/4) c (n/4) log (n/4) h+1 4 c (n/4) log (n/4) c (n / 2 k ) log (n / 2 k ) 2 k c (n/2 k ) log (n/2 k ) c (n / 2 k ) log (n / 2 k ) 2 k c (n/2 k ) log (n/2 k ) c 2 c 2 c 2 c 2 c 2 c 2 c 2 c 2 n/2 c (2) log (2) c 2 c 2 c 2 c 2 c 2 c 2 c 2 c 2 n/2 c (2) log (2) Altezza albero h? c h i=1 n log n h cnlogn 2 i 2 i Altezza albero h? n / 2 h = 2 cioè h = log 2 n - 1 c h i=1 n log n hcnlogn 2 i 2 i 117 118 Coppia di punti più vicini: complessità algoritmo Complessità algoritmo. T(n) 2T( n/2) + O(n log n) T(n) = O(n log 2 n) Domanda. Possiamo ottenere O(n log n)? Coppia di punti più vicini: complessità algoritmo Closest-Pair(p 1,, p n ) { Indichiamo con T(n) la complessità dell algoritmo per n punti Calcolare linea di separazione L tale che divide i punti in due parti uguali. δ 1 = Closest-Pair(metà sinistra) δ 2 = Closest-Pair(metà destra) δ = min(δ 1, δ 2 ) Cancellare tutti punti con distanza >δ da L Ordinare i punti rimanenti per coordinata y. Scansione punti ordinati rispetto ad y e confrontare distanza tra ogni punto ed i successivi 11 punti. Se una distanza è <δ, aggiornare δ. O(n log n) 2T(n / 2) O(n) O(n log n) O(n) } return δ 119 120
Coppia di punti più vicini: complessità algoritmo Coppia di punti più vicini: algoritmo O(n log n) Complessità algoritmo. P x = lista P ordinata rispetto a coordinata x P y = lista P ordinata rispetto a coordinata y T(n) 2T( n/2) + O(n log n) T(n) = O(n log 2 n) Domanda. Possiamo ottenere O(n log n)? Risposta. Si! Non ordinare punti ogni volta. Due liste ordinate all inizio: rispetto ad x e rispetto ad y Ogni chiamata ricorsiva ritorna due liste: tutti i punti ordinati per coordinata y e tutti i punti ordinati per coordinata x. Estrazione delle due liste ordinate dalla singola lista già ordinata. Q = punti nelle prime " n /2# posizioni in P x R = punti nelle ultime " n /2# posizioni in P x Q x = punti in Q ordinati rispetto ad x Q y = punti in Q ordinati rispetto ad y R x = punti in R ordinati rispetto ad x R y = punti in R ordinati rispetto ad y T(n) 2T( n/2) + O(n) T(n) = O(n log n) 121 122 Aritmetica su interi: addizione 5.5 Integer Multiplication Addizione. Dati due interi di n-digit a e b, computare a + b. O(n) operazioni su bit. 1 + 1 1 1 1 1 1 1 0 1 0 1 1 1 0 1 0 1 1 0 1 0 1 0 1 1 1 0 1 0 0 1 0 Addizione 124
Aritmetica su interi: moltiplicazione Moltiplicazione Divide-and-Conquer: Warmup Multiplicazione. Dati due interi di n-digit a e b, computare a b. Soluzione naïve: Θ(n 2 ) operazioni su bit. Per moltiplicare due interi di n-digit: Multiplicare quattro interi di ½n cifre. Addizionare due interi di ½n cifre, e poi shift per ottenere risultato. 1 1 0 1 0 1 0 1 * 0 1 1 1 1 1 0 1 1 1 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 1 0 1 0 1 1 0 1 0 1 0 1 0 1 1 0 1 0 1 0 1 0 Multiplicazione 1 1 0 1 0 1 0 1 0 1 1 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 1 0 x = 2 n /2 x 1 + x 0 y = 2 n /2 y 1 + y 0 ( ) ( 2 n /2 y 1 + y 0 ) = 2 n x 1 y 1 + 2 n /2 x 1 y 0 + x 0 y 1 xy = 2 n /2 x 1 + x 0 ( ) T(n) = 4T n /2 + Θ(n) chiamate ricorsive assumiamo n potenza di 2 addizioni, shift T(n) = Θ(n 2 ) ( ) + x 0 y 0 125 126 Prova con Albero di Ricorsione Prova con Albero di Ricorsione ( ) T(n) = 4T n /2 + Θ(n) chiamate ricorsive addizioni, shift T(n) = Θ(n 2 ) ( ) T(n) = 4T n /2 + Θ(n) chiamate ricorsive addizioni, shift T(n) = Θ(n 2 ) c n c n T(n) c(n/2) c(n/2) c(n/2) c(n/2) 4 c (n/2) c n T(n/2) T(n/2) T(n/2) T(n/2) c n/4 c n/4 c n/4 c n/4 c n/4 c n/4 c n/4 c n/4 c n / 2 k h+1 16 c (n/4) 4 k c (n/2 k ) c 2 c 2 c 2 c 2 c 2 c 2 c 2 c 2 4 h c (2) Altezza albero h? c 4 n h 1 i cn 2 i =cn(2 h 1) da ϑ i 2 i i=0 i=0 i=0 = ϑ h 1 ϑ 1 h 1 h 1 127 128
Prova con Albero di Ricorsione Moltiplicazione: Algoritmo di Karatsuba ( ) T(n) = 4T n /2 + Θ(n) chiamate ricorsive c n addizioni, shift T(n) = Θ(n 2 ) c n Moltiplicazione di due interi con n cifre: Addizionare due interi con ½n cifre. Multiplicare tre interi con ½n cifre. Addizione, sottrazione, e shift di interi con ½n cifre per ottenere risultato. c(n/2) c(n/2) c(n/2) c(n/2) 4 c (n/2) x = 2 n /2 x 1 + x 0 y = 2 n /2 y 1 + y 0 ( ) + x 0 y 0 xy = 2 n x 1 y 1 + 2 n /2 x 1 y 0 + x 0 y 1 c n/4 c n/4 c n/4 c n/4 c n/4 c n/4 c n/4 c n/4 h+1 16 c (n/4) ( ) + x 0 y 0 = 2 n x 1 y 1 + 2 n /2 (x 1 + x 0 )(y 1 + y 0 ) x 1 y 1 x 0 y 0 A B A C C c n / 2 k 4 k c (n/2 k ) c 2 c 2 c 2 c 2 c 2 c 2 c 2 c 2 4 h c (2) h 1 h 1 Altezza albero h? n / 2 h = 2 cioè h = log 2 n - 1 c 4 n i cn 2 i =cn(2 h 1) 2 i i=0 i=0 129 130 Moltiplicazione: Algoritmo di Karatsuba Moltiplicazione: Algoritmo di Karatsuba Moltiplicazione di due interi con n cifre: Addizionare due interi con ½n cifre. Multiplicare tre interi con ½n cifre. Addizione, sottrazione, e shift di interi con ½n cifre per ottenere risultato. Moltiplicazione di due interi con n cifre: Addizionare due interi con ½n cifre. Multiplicare tre interi con ½n cifre. Addizione, sottrazione, e shift di interi con ½n cifre per ottenere risultato. x = 2 n /2 x 1 + x 0 y = 2 n /2 y 1 + y 0 xy = 2 n x 1 y 1 + 2 n /2 x 1 y 0 + x 0 y 1 ( ) + x 0 y 0 ( ) + x 0 y 0 = 2 n x 1 y 1 + 2 n /2 (x 1 + x 0 )(y 1 + y 0 ) x 1 y 1 x 0 y 0 A B A C C x = 2 n /2 x 1 + x 0 y = 2 n /2 y 1 + y 0 xy = 2 n x 1 y 1 + 2 n /2 x 1 y 0 + x 0 y 1 ( ) + x 0 y 0 ( ) + x 0 y 0 = 2 n x 1 y 1 + 2 n /2 (x 1 + x 0 )(y 1 + y 0 ) x 1 y 1 x 0 y 0 A B A C C Teorema. [Karatsuba-Ofman, 1962] La complessità dellalgoritmo di moltiplicazione di due interi con n cifre richiede O(n 1.585 ) operazioni sui bit. Prova. ( ) + T ( n /2 ) + T ( 1+ n /2 ) T(n) T # n /2$ % & % & chiamate ricorsive T(n) = O(n log 2 3 ) = O(n 1.585 ) + Θ(n) addizioni, suttrazioni, shift 131 132
Prova con Albero di Ricorsione Prova con Albero di Ricorsione ( ) + T ( n /2 ) + T ( 1+ n /2 ) T(n) T # n /2$ % & % & chiamate ricorsive + Θ(n) addizioni, suttrazioni, shift T(n) T ( # n /2$ ) + T ( % n /2& ) + T ( 1+ % n /2& ) + Θ(n) T(n) = O(n log 2 3 ) = O(n 1.585 ) chiamate ricorsive addizioni, suttrazioni, shift T(n) = O(n log 2 3 ) = O(n 1.585 ) c n c n T(n) c(n/2) c(n/2) c(n/2) 3 c (n/2) c n T(n/2) T(n/2) T(n/2) c n/4 c n/4 c n/4 c n/4 c n/4 c n/4 c n/4 c n/4 c n/4 c n / 2 k h+1 9 c (n/4) 3 k c (n/2 k ) c 2 c 2 c 2 c 2 c 2 c 2 3 h c (2) da h 1 ϑ i = ϑ h 1 i=0 ϑ 1 133 Altezza albero h? n / 2 h h 1 = 2 cioè h = log 2 n - 1 c 3 n i cn h 1 % 3 ' ( i % * 2 i & 2) =O n % ' 3( h ( ' & 2 * * ) log i=0 i=0 & ) " 3% 2 n n $ ' = n 3log 2 n # 2 & 2 = log 2 n 3log n 2 = n log 2 3 134 Relazione ricorrenza: caso generale con q>2 T(n) qt ( n /2 ) + cn T(n) = O(n log 2 q ) Matrix Multiplication c n c n c(n/2) c(n/2) c(n/2) q c (n/2) c n/4 c n/4 c n/4 c n/4 c n/4 c n/4 c n/4 c n/4 c n/4 h+1 q 2 c (n/4) c n / 2 k q k c (n/2 k ) c 2 c 2 c 2 c 2 c 2 c 2 q h c (2) Altezza albero h? n / 2 h h 1 = 2 cioè h = log 2 n - 1 c q n i cn h 1 % q ' ( i % * i=0 2 i & 2) =O n % ' q( h ( ' & 2 * * ) i=0 & ) # q n % & log 2 n ( = n qlog 2 n $ 2' 2 = log2 n qlog 2 n 135
Moltiplicazione di matrici Moltiplicazione di matrici: prima idea Moltiplicazione di matrici. Date due matrici n-per-n A e B, computa C = AB. n c ij = a ik b kj k=1 " c 11 c 12 c 1n % $ ' $ c 21 c 22 c 2n ' = $ ' $ ' # c n1 c n2 c nn & Algoritmo naïve. Θ(n 3 ) operazioni aritmetiche. for i 1 to n for j 1 to n c ij 0 for k 1 to n c ij c ij + a ik b kj " a 11 a 12 a 1n % $ ' $ a 21 a 22 a 2n ' $ ' $ ' # a n1 a n2 a nn & " b b b % 11 12 1n $ ' $ b 21 b 22 b 2n ' $ ' $ # b n1 b n2 ' b nn & Divide-and-conquer. Divide: partizionare A e B in blocchi ½n-per-½n. Conquer: moltiplicare 8 blocchi ½n-by-½n ricorsivamente. Combine: addizionare prodotti usando 4 addizioni tra matrici. " C 11 C 12 % " $ ' = A 11 A 12 % " $ ' B 11 B 12 % $ ' # C 21 C 22 & # A 21 A 22 & # B 21 B 22 & Complessità? ( ) + ( A 12 B 21 ) ( ) + ( A 12 B 22 ) ( ) + ( A 22 B 21 ) ( ) + ( A 22 B 22 ) C 11 = A 11 B 11 C 12 = A 11 B 12 C 21 = A 21 B 11 C 22 = A 21 B 12 Domanda. E possibile fare meglio dell algoritmo naïve? 137 138 Moltiplicazione di matrici: prima idea Moltiplicazione di matrici: algoritmo efficiente, idea di base Divide-and-conquer. Divide: partizionare A e B in blocchi ½n-per-½n. Conquer: moltiplicare 8 blocchi ½n-by-½n ricorsivamente. Combine: addizionare prodotti usando 4 addizioni tra matrici. Idea di base. Moltiplicare blocchi 2-per-2 di matrici con 7 moltiplicazioni. " C 11 C 12 % " A $ ' = 11 A 12 % " $ ' B 11 B 12 % $ ' P 1 = A 11 (B 12 B 22 ) # C 21 C 22 & # A 21 A 22 & # B 21 B 22 & P 2 = ( A 11 + A 12 ) B 22 " C 11 C 12 % " $ ' = A 11 A 12 % " $ ' B 11 B 12 % $ ' # C 21 C 22 & # A 21 A 22 & # B 21 B 22 & ( ) + ( A 12 B 21 ) ( ) + ( A 12 B 22 ) ( ) + ( A 22 B 21 ) ( ) + ( A 22 B 22 ) C 11 = A 11 B 11 C 12 = A 11 B 12 C 21 = A 21 B 11 C 22 = A 21 B 12 C 11 = P 5 + P 4 P 2 + P 6 C 12 = P 1 + P 2 C 21 = P 3 + P 4 C 22 = P 5 + P 1 P 3 P 7 P 3 = ( A 21 + A 22 ) B 11 P 4 = A 22 (B 21 B 11 ) P 5 = ( A 11 + A 22 ) (B 11 + B 22 ) P 6 = ( A 12 A 22 ) (B 21 + B 22 ) P 7 = ( A 11 A 21 ) (B 11 + B 12 ) Complessità? ( ) T(n) = 8T n /2 chiamate ricorsive + Θ(n 2 ) addizioni, costruzione sottomatrici T(n) = Θ(n 3 ) 7 moltiplicazioni. 18 = 10 + 8 addizioni (o sottrazioni). 139 140
The image cannot be displayed. Your computer may not have enough memory to open the image, or the image may have been corrupted. Restart your computer, and then open the file again. If the red x still appears, you may have to delete the Moltiplicazione di matrici: algoritmo efficiente Moltiplicazione di matrici: algoritmi efficienti in teoria Moltiplicazione efficiente di matrici. (Strassen, 1969) Divide: partizionare A e B in blocchi ½n-per-½n. Compute: 14 matrici ½n-per-½n mediante 10 addizioni di matrici. Conquer: moltiplicare 7 matrici ½n-per-½n ricorsivamente. Combine: 7 prodotti in 4 termini usando 8 addizioni di matrici. Analisi. Assumiamo n potenza di 2. Sia T(n) il numero di operazioni aritmetiche. D. Moltiplicazione due matrici 2-per-2 con solo 7 moltiplicazioni scalari? R. Si! [Strassen, 1969] D. Moltiplicazione due matrici 2-per-2 con solo 6 moltiplicazioni scalari? R. Impossibile. [Hopcroft and Kerr, 1971] Θ(n log 2 6 ) = O(n 2.59 ) D. Due matrici 3-per-3 con solo 21 moltiplicazioni scalari? R. Impossibile. Θ(n log 3 21 ) = O(n 2.77 ) D. Due matrici 70-by-70 con solo 143.640 moltiplicazioni scalari? R. Si! [Pan, 1980] Θ(n log 70 143640 ) = O(n 2.80 ) ( ) T(n) = 7T n /2 chiamate ricorsive + Θ(n 2 ) addizioni, sottrazioni T(n) = Θ(n log 2 7 ) = O(n 2.81 ) Miglior risultato finora. O(n 2.376 ) [Coppersmith-Winograd, 1987.] Congettura. O(n 2+ε ) per ogni ε > 0. I miglioramenti teorici a Strassen sono sempre meno pratici. 141 142 Divide-and-Conquer Quicksort Divide-and-conquer. Dividere il problema in diverse parti. Risolvere ogni parte ricorsivamente. Combinare le soluzioni dei sottoproblemi in soluzioni globali. Uso più comune. Dividere il problema di taglia n in due parti. Risolvere ogni parte ricorsivamente. Combinare le soluzioni dei sottoproblemi in soluzioni globali in tempo lineare. 144
Ordinamento Quicksort Ordinamento. Dati n elementi, disporli in ordine crescente. Applicazioni ovvie: List files in a directory. Organize an MP3 library. List names in a phone book. Display Google PageRank results. Problemi più semplici dopo ordinamento. Find the median. Find the closest pair. Binary search in a database. Identify statistical outliers. Find duplicates in a mailing list. Applicazioni non-ovvie: Data compression. Computer graphics. Interval scheduling. Computational biology. Minimum spanning tree. Supply chain management. Simulate a system of particles. Book recommendations on Amazon. Load balancing on a parallel computer.... Divide-and-conquer. Divide: dividi lista in due parti, in modo che ogni elemento della prima parte sia di ogni elemento della seconda parte. Conquer: ordina ricorsivamente ognuna delle due parti. Combine: sono già ordinati. Abbiamo già visto il Mergesort come algoritmo di ordinamento (complessità O(n log n) ). 145 146 Quicksort Quicksort: algoritmo Divide-and-conquer. Divide: partiziona A[p r] in due parti A[p q-1] e A[q+1 r] in modo che ogni elemento di A[p q-1] sia A[q] ed ogni elemento di A[q+1 r] sia >A[q]. (Il valore q è scelto dalla procedura di partizione.) p q-1 q q+1 r Quicksort (A, p, r) if p < r then q Partiziona (A, p, r) Quicksort (A, p, q - 1) Quicksort (A, q + 1, r) A[q] >A[q] Conquer: ordina ricorsivamente ognuna delle due parti. Combine: sono già ordinati. Per ordinare l array A, chiamata iniziale Quicksort (A, 1, length[a]). 147 148
Partiziona: idea Partiziona: idea 149 150 Partiziona: algoritmo Partiziona: esempio Esempio. Partiziona (A, p, r) x A[r] i p 1 for j p to r 1 do if A[j] x then i i + 1 scambia A[i] A[j] scambia A[i + 1] A[r] return i + 1 Partiziona (A, p, r) x A[r] i p 1 for j p to r 1 do if A[j] x then i i + 1 scambia A[i] A[j] scambia A[i + 1] A[r] return i + 1 151 152
Partiziona: complessità Partizionamento Partiziona (A, p, r) x A[r] i p 1 for j p to r 1 do if A[j] x then i i + 1 scambia A[i] A[j] scambia A[i + 1] A[r] return i + 1 Partizionamento: Analizziamo tre casi Caso peggiore Caso migliore Caso medio Complessità: Θ(n), dove n = r - p + 1 153 154 Partizionamento: caso peggiore Partizionamento: caso migliore Caso peggiore. Partizione sbilanciata con sottoproblemi di n-1 e 0 elementi T(n) = T(n - 1) + T(0) + Θ(n) = T(n - 1) + Θ(n). Soluzione T(n) = Θ(n 2 ) Caso migliore. Partizione bilanciata con sottoproblemi di " n /2# e " n /2# 1 T(n) = 2 T(n/2) + Θ(n) Soluzione T(n) = Θ(n log n) (è la stessa relazione del Mergesort) 155 156
Partizione bilanciata Prova con Albero di Ricorsione Partizione bilanciata con sottoproblemi di 9n/10 e n/10 elementi Risoluzione T(n) = T (9n/10) + T (n/10) + cn T(n) T (9n/10) + T (n/10) + cn T(n) cn cn cn T(n/10) T(9n/10) c n/10 c 9n/10 cn cn/10 cn c9n/10 c c n/100 c 9n/100 c 9n/100 c 81n/100 h+1 cn... cn T(n/100) T(9n/100) T(9n/100) T(81n/100) c... cn Altezza albero h? cn (h+1) 157 158 Prova con Albero di Ricorsione Partizione bilanciata Risoluzione T(n) = T (9n/10) + T (n/10) + cn cn cn c n/10 c 9n/10 cn c c n/100 c 9n/100 c 9n/100 c 81n/100 h+1 cn... cn... c cn Altezza albero h? (9/10) h n = 1 cioè h = log 10/9 n cn (h+1) 159 160
Partizioni Quicksort: analisi caso peggiore Partizione sbilanciata seguita da partizione bilanciata T(n) = max 0 q n-1 (T(q) + T(n- q-1)) + Θ(n) Proviamo per induzione che T (n) cn 2 per qualche costante c. n costo 2 partizioni Θ(n) n costo partizione Θ(n) Sostituendo: T(n) max 0 q n-1 (cq 2 + c(n- q-1) 2 ) + Θ(n) c max 0 q n-1 (q 2 + (n- q-1) 2 ) + Θ(n) 0 (n-1)/2-1 n-1 (n-1)/2 (n-1)/2 Caso medio: Intuitivamente è più vicino al caso migliore che al caso peggiore. Complessità O(n log n) (n-1)/2 La funzione f(q) = q 2 +(n-q-1) 2 ha un massimo nell intervallo 0 q n - 1 in un punto estremo, dato che la derivata seconda f (q) > 0 max 0 q n-1 (q 2 + (n- q-1) 2 ) (n-1) 2 = n 2-2n +1 Quindi, T(n) cn 2 - c(2n - 1) + Θ(n) cn 2 Dato che si può scegliere la costante c grande abbastanza affinchè il termine c(2n - 1) domina il termine Θ(n). Quindi, T(n) = O(n 2 ). 161 162 Esercizio 7.2-3 Esercizio 7.2-5 Se gli elementi sono distinti e sono già ordinati in senso decrescente, la complessità del Quicksort è Θ(n 2 ). Supponiamo che la partizione ad ogni livello è proporziale ad 1-a ed a, dove 0 < α 1/2 è una costante. Mostrare che la profondità minima di una foglia nell albero della ricorsione è approssimativamente - lg n/ lg α e la massima profondità è approssimativamente - lg n/ lg (1-α). (Trascurare l arrotondamento agli interi.) 163 164
Quicksort: versione randomizzata Quicksort: Cenno storico Partiziona_random (A, p, r) i random(p,r) scambia A[i] A[r] return Partiziona(A, p, r) La procedura del quicksort è dovuta ad Hoare: C. R. Hoare. Quicksort. Computer Journal, 5(1): 10 15, 1962. La versione di Hoare appare nel Problema 7-1. La procedura Partizione che abbiamo visto è dovuta a N. Lomuto. Quicksort_random (A, p, r) if p < r then q Partiziona_random (A, p, r) Quicksort_random (A, p, q - 1) Quicksort_random (A, q + 1, r) 165 166 Esercizi Esercizio: Potenze di un numero Potenze di un numero Numeri di Fibonacci Massima Sottosequenza Massimi in 2-D Defective Chessboards Input: a, n N Calcolare: a n Algoritmo naïve: Θ(n) Algoritmo Divide and Conquer Θ(log n) Esercizi da risolvere in forma completa a casa 167 168
Esercizio: Potenze di un numero Esercizio: Potenze di un numero Input: a, n N Calcolare: a n Algoritmo naïve: Θ(n) Algoritmo Divide and Conquer Θ(log n)! # a n = " $# Complessità algoritmo Divide and Conquer: Relazione ricorrenza running time T(n) = T(n/2) + Θ(1) Soluzione T(n) = Θ(log n) (a n/2 ) 2 se n pari (a (n-1)/2 ) 2 a se n dispari Soluzione relazione ricorrenza con metodo di sostituzione T(n) = T(n/2) + c = T(n/4) + c + c = T(n/4) + 2c = T(n/8) + c + 2c = T(n/8) + 3c = T(n/16) + c + 3c = T(n/16) + 4c = = T(n/2 k ) + kc = Θ(k) = Θ(log n) con n = 2 k da n 2 k =1 segue che k = log n 169 170 Esercizio: Numeri di Fibonacci Esercizio: Numeri di Fibonacci Input: n N + Calcolare: F n! # F n = " # $ 0 1 1 2 3 5 8 13 21 34 0 se n = 0 1 se n =1 F n-1 +F n-2 se n 2 Algoritmo naïve: Θ(n) Algoritmo Divide and Conquer Θ(log n) Input: n N Calcolare: F n! # F n = " # $ 0 se n = 0 1 se n =1 F n-1 +F n-2 se n 2 Suggerimento per algoritmo Divide and Conquer Θ(log n)! # " # F n+1 F n F n F n-1 $ & % & =! 1 1 $ # & " 1 0 % n Provare la relazione (per induzione su n) Mostrare come realizzare un algoritmo Divide and Conquer Θ(log n) 171 172
Esercizio: Massima Sottosequenza Esercizio: Massima Sottosequenza Input: sequenza A[1], A[2],, A[n] Calcolare: sottosequenza con somma massima elementi consecutivi 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 13-3 -25 20-3 -16-23 18 20-7 12-5 -22 15-4 7 20 18+20-7+12 = 43 Algoritmo naïve: Θ(n 2 ) Algoritmo Divide and Conquer Θ(n log n) 15-4+7 = 18 Input: sequenza A[1], A[2],, A[n] Calcolare: sottosequenza con somma massima Divide-and-conquer. Divide: dividere sequenza in due parti della stessa grandezza. Conquer: risolvere ricorsivamente il problema in ogni parte. Combine: calcolare la sottosequenza con somma massima che contiene il punto di mezzo (cioè con inizio e fine in parti diverse), e restituire il massimo delle 3 somme. low mid mid+1 high 173 174 Esercizio: Massima Sottosequenza Esercizio: Massimi in 2-D Combine: calcolare la sottosequenza con somma massima che contiene il punto di mezzo (cioè con inizio e fine in parti diverse), e restituire il massimo delle 3 somme. Input: insieme di punti in un piano Calcolare: punti di massimo low mid mid+1 high Un punto (x 1,y 1 ) domina (x 2,y 2 ) se x 1 > x 2 e y 1 > y 2. Un punto è un massimo se non è dominato da altri punti. leftsum A[mid] sum A[mid] maxleft mid for i = mid-1 downto low sum sum + A[i] ; if sum > leftsum leftsum sum maxleft i rightsum A[mid+1] sum A[mid+1] maxright mid+1 for j = mid+1 to high sum sum + A[j] if sum > rightsum rightsum sum maxright j Massima somma per sottosequenza che contiene A[mid] e A[mid+1] : leftsum + rightsum Algoritmo naïve: Θ(n 2 ) Algoritmo Divide and Conquer Θ(n log n) 175 176
Esercizio: Massimi in 2-D Esercizio: Massimi in 2-D Input: insieme di punti in un piano Calcolare: punti di massimo Input: insieme di punti in un piano Calcolare: punti di massimo Divide-and-conquer. Divide: dividere punti in due parti della stessa grandezza mediante una linea verticale. Conquer: risolvere ricorsivamente il problema in ognuna delle 2 parti. Combine: Divide-and-conquer. Divide: dividere punti in due parti della stessa grandezza mediante una linea verticale. Conquer: risolvere ricorsivamente il problema in ognuna delle 2 parti. Combine: eliminare i punti di massimo della parte sinistra la cui ordinata è minore della massima ordinata di un punto di massimo nella parte destra. Restituire i punti di massimo delle due parti. eliminare P 3 perchè dominato da P 8 177 178 Esercizio: Massimi in 2-D Esercizio: Defective Chessboards Input: insieme di punti in un piano Calcolare: punti di massimo Divide-and-conquer. Divide: dividere punti in due parti della stessa grandezza mediante una linea verticale. Conquer: risolvere ricorsivamente il problema in ogni parte. Combine: eliminare i punti di massimo della parte sinistra la cui ordinata è minore della massima ordinata di un punto di massimo nella parte destra. Restituire i punti di massimo delle due parti. Input: scacchiera n n e casella non disponibile (assumere n potenza di 2) Calcolare: ricoprimento con triomini Una Defective Chessboard è una scacchiera con una casella non disponibile È quella del punto di massimo con minore ascissa. Perchè? 1x1 2x2 4x4 8x8 eliminare P 3 perchè dominato da P 8 179 180
Esercizio: Defective Chessboards Esercizio: Defective Chessboards Input: scacchiera n n e casella non disponibile Calcolare: ricoprimento con triomini Input: scacchiera n n e casella non disponibile Calcolare: ricoprimento con triomini, cioè posizionamento di (n 2-1)/3 triomini sulla scacchiera in modo da ricoprire tutte le caselle disponibili. Un triomino è un oggetto a forma di L che copre 3 caselle di una scacchiera. Ha 4 orientazioni: 1x1 2x2 4x4 8x8 181 182 Esercizio: Defective Chessboards Esercizio: Defective Chessboards Input: scacchiera n n e casella non disponibile Calcolare: ricoprimento con triomini, cioè posizionamento di (n 2-1)/3 triomini sulla scacchiera in modo da ricoprire tutte le caselle disponibili. Input: scacchiera n n e casella non disponibile Calcolare: ricoprimento con triomini, cioè posizionamento di (n 2-1)/3 triomini sulla scacchiera in modo da ricoprire tutte le caselle disponibili. 1x1 2x2 4x4 8x8 1x1 2x2 4x4 8x8 183 184
Esercizio: Defective Chessboards Esercizio: Defective Chessboards Input: scacchiera n n e casella non disponibile Calcolare: ricoprimento con triomini, cioè posizionamento di (n 2-1)/3 triomini sulla scacchiera in modo da ricoprire tutte le caselle disponibili. Input: scacchiera n n e casella non disponibile Calcolare: ricoprimento con triomini, cioè posizionamento di (n 2-1)/3 triomini sulla scacchiera in modo da ricoprire tutte le caselle disponibili. 1x1 2x2 4x4 8x8 1x1 2x2 4x4 8x8 185 186 Esercizio: Defective Chessboards Esercizio: Defective Chessboards Input: scacchiera n n e casella non disponibile Calcolare: ricoprimento con triomini, cioè posizionamento di (n 2-1)/3 triomini sulla scacchiera in modo da ricoprire tutte le caselle disponibili. Input: scacchiera n n e casella non disponibile Calcolare: ricoprimento con triomini, cioè posizionamento di (n 2-1)/3 triomini sulla scacchiera in modo da ricoprire tutte le caselle disponibili. 1x1 2x2 4x4 8x8 1x1 2x2 4x4 8x8 187 188
Esercizio: Defective Chessboards Esercizio: Defective Chessboards Input: scacchiera n n e casella non disponibile Calcolare: ricoprimento con triomini, cioè posizionamento di (n 2-1)/3 triomini sulla scacchiera in modo da ricoprire tutte le caselle disponibili. Input: scacchiera n n e casella non disponibile Calcolare: ricoprimento con triomini, cioè posizionamento di (n 2-1)/3 triomini sulla scacchiera in modo da ricoprire tutte le caselle disponibili. Divide-and-conquer Divide: dividere scacchiera in quattro scacchiere. 1x1 2x2 4x4 4x4 4x4 8x8 189 190 Esercizio: Defective Chessboards Esercizio: Defective Chessboards Input: scacchiera n n e casella non disponibile Calcolare: ricoprimento con triomini, cioè posizionamento di (n 2-1)/3 triomini sulla scacchiera in modo da ricoprire tutte le caselle disponibili. 8x8 Divide-and-conquer Divide: dividere scacchiera in quattro scacchiere. Conquer: rendere defective le altre tre scacchiere e risolvere ricorsivamente il problema per ogni scacchiera. Combine: Restituire i ricoprimenti delle quattro parti con in aggiunta il triomino centrale. Relazione ricorrenza running time T(n) = 4 T(n/2) + Θ(1) Soluzione T(n) = Θ(n 2 ) Soluzione relazione ricorrenza con metodo di sostituzione T(n) = 4 T(n/2) + c con n=2 k = 4 (4 T(n/4) + c) + c = 4 2 T(n/4) + 4c + c = 4 2 (4 T(n/8) + c) + 4c + c = 4 3 T(n/8) + 4 2 c + 4c + c = 4 3 (4 T(n/16) + c) + 4 2 c + 4c + c = 4 4 T(n/16) + 4 3 c + 4 2 c + 4c + c = = 4 k T(n/2 k ) + 4 k-1 c + 4 k-2 c + 4 3 c + 4 2 c + 4c + c = Θ(4 k ) = Θ(n 2 ) da k 1 ϑ i i=0 k 1 segue che 4 i = 4k 1 3 i=0 = ϑ k 1 ϑ 1 191 192
Riepilogo Capitolo 5, Divide and Conquer 5.1 Mergesort 5.2 Recurrence Relations 5.3 Counting Inversions 5.4 Closest Pair of Points 5.5 Integer Multiplication 5.6 Fast Fourier Transform (no) Matrix Multiplication Esercizi Potenze di un numero Numeri di Fibonacci Massima Sottosequenza Massimi in 2-D Defective Chessboards Quicksort Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein Introduction to Algorithms, Second Edition The MIT Press 2001 (Cap. 7 Quicksort) In italiano: Introduzione agli algoritmi e strutture dati 2/ed McGraw-Hill, Maggio 2005 193