Introduzione agli algoritmi Giuseppe F. Italiano Università di Roma “Tor Vergata” [email protected] Introduzione agli algoritmi Giuseppe F. Italiano Cos’è un algoritmo? L’etimologia NON è da αλγος e αριθµος (dolore per i numeri!) Muhammad al-Khowarizmi, da un francobollo commemorativo russo del 1983 (immagine scannerizata da Donald E. Knuth) 2 Scuola Estiva di Calcolo Avanzato 1 Introduzione agli algoritmi Giuseppe F. Italiano Cos’è un algoritmo? Insieme di istruzioni, definite passo per passo, in modo da poter essere eseguite meccanicamente e tali da produrre un determinato risultato • Esempio: algoritmo preparaCaffè 3 Introduzione agli algoritmi Scuola Estiva di Calcolo Avanzato Giuseppe F. Italiano Cos’è un algoritmo? 4 Scuola Estiva di Calcolo Avanzato 2 Introduzione agli algoritmi Giuseppe F. Italiano Cosa NON è un algoritmo? Algoritmo di Martin (How to become a millionaire) Get a million dollars. Don’t pay taxes. If you get caught, Say “I forgot.” S. Martin, “You Can Be A Millionaire”, Saturday Night Live, January 21, 1978. Reprinted in Comedy Is Not Pretty, Warner Bros. Records, 1979. Scuola Estiva di Calcolo Avanzato 5 Introduzione agli algoritmi Giuseppe F. Italiano Perché algoritmi? • Gli algoritmi sono alla base di applicazioni: i.e., forniscono descrizione astratta / formale di un metodo (procedimento) per giungere alla soluzione di un dato problema 6 Scuola Estiva di Calcolo Avanzato 3 Introduzione agli algoritmi Giuseppe F. Italiano Outline 1. Introduzione (Fibonacci toy problem) 2. Tecniche algoritmiche 3. Algoritmi cache oblivious Scuola Estiva di Calcolo Avanzato 7 Introduzione agli algoritmi Giuseppe F. Italiano Introduzione a progetto e analisi di algoritmi efficienti tramite un esempio “giocattolo”: Calcolo dei numeri di Fibonacci (problema semplice ma con molte soluzioni) 8 Scuola Estiva di Calcolo Avanzato 4 Introduzione agli algoritmi Giuseppe F. Italiano L’isola dei conigli Leonardo da Pisa (noto anche come Fibonacci) si interessò di molte cose, tra cui il seguente problema (dinamica delle popolazioni): Quanto velocemente si espande una popolazione di conigli sotto appropriate condizioni? In particolare, se partiamo da una coppia di conigli (in un’isola deserta), quante coppie si avranno nell’anno n? Scuola Estiva di Calcolo Avanzato 9 Introduzione agli algoritmi Giuseppe F. Italiano Modello e ipotesi sui conigli • Una coppia di conigli genera due coniglietti ogni anno • I conigli cominciano a riprodursi soltanto al secondo anno dopo la loro nascita • I conigli sono immortali (!) L’ultima ipotesi può sembrare irrealistica Semplifica il problema: risolvere e verificare 10 Scuola Estiva di Calcolo Avanzato 5 Introduzione agli algoritmi Giuseppe F. Italiano Tasso di riproduzione dei conigli Fn : numero di coppie di conigli presenti nell’anno n F1 F2 F3 F4 F5 = = = = = 1 1 2 3 5 (una sola coppia) (troppo giovani per procreare) (prima coppia di coniglietti) (seconda coppia di coniglietti) (prima coppia di nipotini) Per completezza supporremo F0 = 0 11 Introduzione agli algoritmi Scuola Estiva di Calcolo Avanzato Giuseppe F. Italiano I conigli di Fibonacci Scuola Estiva di Calcolo Avanzato 6 Introduzione agli algoritmi Giuseppe F. Italiano L’albero dei conigli La riproduzione dei conigli può quindi essere descritta da: Scuola Estiva di Calcolo Avanzato 13 Introduzione agli algoritmi Giuseppe F. Italiano Regola di espansione • In generale in un certo anno ci saranno tutte le coppie dell’anno precedente, più una nuova coppia di conigli per ogni coppia presente due anni prima • Abbiamo quindi relazione di ricorrenza: Fn = Fn-1 + Fn-2 se n ≥ 3 1 se n = 1,2 • Problema algoritmico: come calcoliamo Fn ? 14 Scuola Estiva di Calcolo Avanzato 7 Introduzione agli algoritmi Giuseppe F. Italiano Un possibile approccio • Possiamo usare direttamente una soluzione alla relazione di Fibonacci: dove: è la sezione aurea di un segmento 15 Introduzione agli algoritmi Scuola Estiva di Calcolo Avanzato Giuseppe F. Italiano Algoritmo fibonacci1 16 Scuola Estiva di Calcolo Avanzato 8 Introduzione agli algoritmi Giuseppe F. Italiano Correttezza? • Qual è l’accuratezza di Φ e Φˆ necessaria per ottenere un risultato corretto? • Ad esempio, se usiamo solo 3 cifre decimali: n fibonacci1(n) arrotondamento Fn 3 16 18 1.99992 986.698 2583.1 2 987 2583 2 987 2584 Scuola Estiva di Calcolo Avanzato 17 Introduzione agli algoritmi Giuseppe F. Italiano Algoritmo fibonacci2 Poiché fibonacci1 non dà risultati corretti, come approccio alternativo potremmo utilizzare direttamente la definizione (ricorsiva) : algoritmo fibonacci2(intero n) → intero if (n ≤ 2) then return 1 else return fibonacci2(n-1) + fibonacci2(n-2) Opera solo con interi E’ una soluzione accettabile? Codice C++ 18 Scuola Estiva di Calcolo Avanzato 9 Introduzione agli algoritmi Giuseppe F. Italiano Tempo di esecuzione algoritmo fibonacci2(intero n) → intero if (n ≤ 2) then return 1 else return fibonacci2(n-1) + fibonacci2(n-2) Se n ≤ 2, tempo costante; Se n ≥ 3: • chiamata a fibonacci2(n-1) • chiamata a fibonacci2(n-2)! 19 Scuola Estiva di Calcolo Avanzato Introduzione agli algoritmi Giuseppe F. Italiano Relazione di ricorrenza Per n ≥ 3 in ogni chiamata si eseguono 2 linee di codice, oltre a quelle eseguite nelle chiamate ricorsive: T(n) = 2 + T(n-1) + T(n-2) A parte il 2, è come per i conigli di Fibonacci! 20 Scuola Estiva di Calcolo Avanzato 10 Introduzione agli algoritmi Giuseppe F. Italiano Relazioni di ricorrenza In generale, tempo richiesto da algoritmi ricorsivi genera relazioni di ricorrenza Il tempo di ogni funzione è pari al tempo speso all’interno della chiamata più il tempo speso nelle chiamate ricorsive Risolvendo la relazione di ricorrenza otteniamo l’espressione del tempo 21 Introduzione agli algoritmi Scuola Estiva di Calcolo Avanzato Giuseppe F. Italiano Alberi della ricorsione • Utile per risolvere relazioni di ricorrenza • Nodi corrispondenti a chiamate ricorsive • Figli di un nodo corrispondenti alle sottochiamate 22 Scuola Estiva di Calcolo Avanzato 11 Introduzione agli algoritmi Giuseppe F. Italiano Alberi della ricorsione Per calcolare F(5) : 4 nodi interni, 2 linee di codice ciascuno 5 foglie, 1 linea di codice ciascuna Totale = 4 * 2 + 5 * 1 = 13 linee di codice Scuola Estiva di Calcolo Avanzato 23 Introduzione agli algoritmi Giuseppe F. Italiano Numero di linee di codice per F(n) • Etichettiamo nodi dell’albero con numero di linee di codice eseguite nella chiamata corrispondente: – ogni nodo interno conta 2 – ogni foglia conta 1 • Per calcolare T(n) basta contare nell’albero della ricorsione: – numero di foglie – numero di nodi interni 24 Scuola Estiva di Calcolo Avanzato 12 Introduzione agli algoritmi Giuseppe F. Italiano Calcolare numero di foglie • Ogni foglia dell’albero della ricorsione contribuisce 1 al valore di F(n) • Numero di foglie dell’albero della ricorsione di fibonacci2(n) è pari a F(n) Scuola Estiva di Calcolo Avanzato 25 Introduzione agli algoritmi Giuseppe F. Italiano Calcolare numero di nodi interni • Dimostreremo per induzione che • Numero di nodi interni di un albero in cui ogni nodo ha zero oppure due figli è pari al numero di foglie - 1 26 Scuola Estiva di Calcolo Avanzato 13 Introduzione agli algoritmi Giuseppe F. Italiano Dimostrazione P (k) : se albero ha k foglie ha (k-1) nodi interni Induzione sul numero di foglie: • Base. P (1) : 1 foglia, 0 nodi interni. Banale. • Passo induttivo. P (k) implica P (k+1) Per generare albero con k+1 foglie, attacchiamo due figli ad una (vecchia) foglia Numero di foglie: k -1 + 2 = k + 1 Numero di nodi interni: (k -1) + 1 = k 27 Introduzione agli algoritmi Scuola Estiva di Calcolo Avanzato Giuseppe F. Italiano Calcolare T(n) • Numero di foglie dell’albero della ricorsione di fibonacci2(n) è pari a F(n) • Numero di nodi interni dell’albero della ricorsione di fibonacci2(n) è pari a F(n) - 1 • In totale numero di linee di codice eseguite è F(n) + 2 ( F(n) – 1 ) = 3 F(n) - 2 28 Scuola Estiva di Calcolo Avanzato 14 Introduzione agli algoritmi Giuseppe F. Italiano Possiamo fare di meglio? fibonacci2 è un algoritmo molto lento: T(n) ≈ F(n) ≈ Φn Perché è lento? Continua a ricalcolare più volte la soluzione dello stesso sottoproblema! Those who cannot remember the past are doomed to repeat it. George Santayana, The Life of Reason, Introduction and Reason in Common Sense (1905) 29 Introduzione agli algoritmi Scuola Estiva di Calcolo Avanzato Giuseppe F. Italiano Programmazione Dinamica! Per evitare di risolvere più volte lo stesso sottoproblema, memorizziamo la soluzione dei vari sottoproblemi in un array. Calcoliamo Fib[i] utilizzando le soluzioni memorizzate per Fib[i-1] e Fib[i-2] 30 Scuola Estiva di Calcolo Avanzato 15 Introduzione agli algoritmi 1 1 1 2 Giuseppe F. Italiano 2 3 5 8 13 21 34 55 89 144 3 4 5 6 7 8 9 10 11 12 Algoritmo fibonacci3 Scuola Estiva di Calcolo Avanzato Introduzione agli algoritmi Giuseppe F. Italiano Algoritmo fibonacci3! algoritmo fibonacci3(intero n) → intero sia Fib un array di n interi Fib[1] ← Fib[2] ← 1 for i = 3 to n do Fib[i] ← Fib[i-1] + Fib[i-2] return Fib[n] Quanto è più veloce di fibonacci2 ? 32 Scuola Estiva di Calcolo Avanzato 16 Introduzione agli algoritmi Giuseppe F. Italiano Tempo richiesto da fibonacci3! algoritmo fibonacci3(intero n) → intero sia Fib un array di n interi Fib[1] ← Fib[2] ← 1 for i = 3 to n do Fib[i] ← Fib[i-1] + Fib[i-2] return Fib[n] 3 linee di codice sono eseguite sempre Prima linea del ciclo eseguita (n-1) volte [ 1 per n=1] Seconda linea del ciclo eseguita (n-2) volte [ 0 per n=1] T(n) = 3 + n-1 + n-2 = 2n [ T(1) = 3+1 = 4 ] Scuola Estiva di Calcolo Avanzato 33 Introduzione agli algoritmi Giuseppe F. Italiano fibonacci3 vs. fibonacci2! • 2n molto meglio di 3Fn-2 • L’algoritmo fibonacci3 impiega tempo proporzionale a n piuttosto che esponenziale in n (fibonacci2) • Tempo effettivo richiesto da implementazioni in C dei due algoritmi su piattaforme diverse: 34 Scuola Estiva di Calcolo Avanzato 17 Introduzione agli algoritmi Giuseppe F. Italiano Occupazione di memoria • Tempo di esecuzione non è sola risorsa che ci interessa. • Tempo di programmazione e lunghezza del codice (Ingegneria del Software) • Anche quantità di memoria richiesta può essere cruciale. • Se algoritmo lento, basta attendere più a lungo • Ma se algoritmo richiede più spazio (RAM) di quello a disposizione, rischiamo di non ottenere mai la soluzione! Scuola Estiva di Calcolo Avanzato 35 Introduzione agli algoritmi Giuseppe F. Italiano Algoritmo fibonacci4 • fibonacci3 usa un array di dimensione n • In realtà non ci serve mantenere tutti i valori di Fn precedenti, ma solo gli ultimi due, riducendo lo spazio a poche variabili in tutto: algoritmo fibonacci4(intero n) → intero a←b←1 for i = 3 to n do c ← a+b a←b b←c return b 36 Scuola Estiva di Calcolo Avanzato 18 Introduzione agli algoritmi Giuseppe F. Italiano Notazione asintotica (1 / 4) • Misurare T(n) come numero di linee di codice mandate in esecuzione è una misura molto approssimativa del tempo di esecuzione • Ipotesi: ogni linea di codice genera codice assembler equivalente 37 Introduzione agli algoritmi Scuola Estiva di Calcolo Avanzato Giuseppe F. Italiano Notazione asintotica (2 / 4) • Vorremmo un modo per descrivere ordine di grandezza di T(n) ignorando dettagli inessenziali come costanti moltiplicative… • Si utilizza a questo scopo la notazione asintotica O( ) 38 Scuola Estiva di Calcolo Avanzato 19 Introduzione agli algoritmi Giuseppe F. Italiano Notazione asintotica (3 / 4) • Diremo che f(n) = O ( g(n) ) se f(n) ≤ c g(n) per qualche costante c, ed n abbastanza grande Scuola Estiva di Calcolo Avanzato 39 Introduzione agli algoritmi Giuseppe F. Italiano • Ad esempio, possiamo rimpiazzare: – T(n) = 3Fn con T(n) = O(Fn) – T(n) = 2n e T(n) = 4n con T(n) = O(n) – T(n) = Fn con O(2n) • Notazione O semplifica la vita: – Trascurare dettagli di basso livello – Confrontare facilmente algoritmi – fibonacci3 e fibonacci4 sono O(n): molto meglio di fibonacci2 - O(2n) ! Codice C++ 40 Scuola Estiva di Calcolo Avanzato 20 Introduzione agli algoritmi Giuseppe F. Italiano Possiamo fare di meglio? • Possiamo calcolare Fn in tempo inferiore a O (n)? • E’ possibile dimostrare (per induzione) la seguente proprietà di matrici: 1 1 1 0 n = Fn+1 Fn Fn Fn-1 • Useremo questa proprietà per progettare un algoritmo più efficiente di fibonacci4! Scuola Estiva di Calcolo Avanzato 41 Introduzione agli algoritmi Giuseppe F. Italiano Potenze ricorsive • Da dove deriva questa proprietà? Fn+1 Fn 1 1 1 0 42 = n = 1 1 1 0 Fn Fn-1 Fn+1 Fn Fn Fn-1 Scuola Estiva di Calcolo Avanzato 21 Introduzione agli algoritmi Giuseppe F. Italiano Algoritmo fibonacci5 • Tempo di esecuzione è ancora O(n) • Cosa abbiamo guadagnato? Scuola Estiva di Calcolo Avanzato 43 Introduzione agli algoritmi Giuseppe F. Italiano Calcolo di potenze • Possiamo calcolare la potenza n-esima elevando al quadrato la potenza (n/2)-esima • Se n è dispari? Eseguiamo una ulteriore moltiplicazione • Esempio: calcolare 38 32 = 9 34 = (9)2 = 81 44 38 = (81)2 = 6561 Scuola Estiva di Calcolo Avanzato 22 Introduzione agli algoritmi Giuseppe F. Italiano Divide et impera Tecnica top-down: 1. Dividi il problema in più sottoproblemi 2. Risolvi (ricorsivamente) i sottoproblemi 3. Ricombina soluzioni dei sottoproblemi per ottenere la soluzione del problema originario Esempi: ricerca binaria, mergesort, quicksort, … 45 Introduzione agli algoritmi Scuola Estiva di Calcolo Avanzato Giuseppe F. Italiano Algoritmo fibonacci6 46 Scuola Estiva di Calcolo Avanzato 23 Introduzione agli algoritmi Giuseppe F. Italiano Tempo di esecuzione • Tutto il tempo è speso nella funzione potenzaDiMatrice! – All’interno della funzione si spende tempo costante – Si esegue una chiamata ricorsiva con input n/2 • L’equazione di ricorrenza è pertanto: T(n) = O(1) + T(n/2) • Come risolverla? Scuola Estiva di Calcolo Avanzato 47 Introduzione agli algoritmi Giuseppe F. Italiano Metodo dell’iterazione T(n) ≤ c + T(n/2) ≤ c + c + T(n/4) = 2c + T(n/22) In generale: T(n) ≤ c k + T(n/2k) Per k = log2 n si ottiene T(n) ≤ c log2 n + T(1) = O(log2 n ) fibonacci6 è quindi esponenzialmente più veloce di fibonacci3! 48 Scuola Estiva di Calcolo Avanzato 24 Introduzione agli algoritmi Giuseppe F. Italiano Riepilogo Tempo di esecuzione Occupazione di memoria fibonacci2! O(2n) O(n) fibonacci3! O(n) O(n) fibonacci4! O(n) O(1) fibonacci5! O(n) O(1) fibonacci6! O(log n) O(log n) Scuola Estiva di Calcolo Avanzato 49 Introduzione agli algoritmi Giuseppe F. Italiano Lunghezza dell’input: |x| = log n Lunghezza dell’output: Y Tempo di esecuzione 50 |x| Occupazione di memoria fibonacci2! O( 22 ) O(2|x| Y) fibonacci3! O( 2|x| ) O(2|x| Y) fibonacci4! O( 2|x| ) O(|x|+Y) fibonacci5! O( 2|x| ) O(|x|+Y) fibonacci6! O( |x| ) O( |x| Y ) Scuola Estiva di Calcolo Avanzato 25 Introduzione agli algoritmi Giuseppe F. Italiano Possiamo fare di meglio? Abbiamo davvero bisogno di matrici? Una matrice è solo una notazione astratta: ciò che importa sono le operazioni (normali operazioni aritmetiche). Usare matrici rischia di produrre un algoritmo poco efficiente in pratica. Per dirne una, calcoliamo sempre due volte (separatamente) Fk per un numero logaritmico di k… 1 1 1 0 k = Fk+1 Fk Fk Fk-1 Scuola Estiva di Calcolo Avanzato 51 Introduzione agli algoritmi Giuseppe F. Italiano Abbiamo davvero bisogno di matrici? Per trovare un algoritmo che non usa matrici, concentriamoci sulla “meccanica” dei calcoli: 1 1 1 0 1 1 1 0 52 2k = k = Fk+1 Fk Fk Fk-1 Fk+1 Fk Fk Fk-1 Fk+1 Fk = Fk Fk-1 F2k+1 F2k F2k F2k-1 Scuola Estiva di Calcolo Avanzato 26 Introduzione agli algoritmi 1 1 1 0 Giuseppe F. Italiano 2k = Fk+1 Fk Fk Fk-1 Fk+1 Fk = Fk Fk-1 F2k+1 F2k F2k F2k-1 Da cui possiamo ricavare: F2k+1 = ( Fk+1 ) 2 + ( Fk ) 2 F2k = Fk Fk+1 + Fk Fk-1 F2k-1 = ( Fk ) 2 + ( Fk-1 ) 2 Scuola Estiva di Calcolo Avanzato Introduzione agli algoritmi Giuseppe F. Italiano F2k+1 = ( Fk+1 ) 2 + ( Fk ) 2 F2k = Fk ( Fk + 2 Fk-1 ) F2k-1 = ( Fk ) 2 + ( Fk-1 ) 2 Ovvero: Fk-1, Fk, Fk+1 F2k-1, F2k, F2k+1 F0, F1, F2 F1, F2, F3 F3, F4, F5 F7, F8, F9 " F15, F16, F17 F31, F32, F33 F63, F64, F65 " F127, F128, F129 F255, F256, F257 F511, F512, F513 F1023, F1024, F1025 … Scuola Estiva di Calcolo Avanzato 27 Introduzione agli algoritmi Giuseppe F. Italiano Algoritmo fibonacci7 Meglio ancora: F2k = Fk ( Fk + 2 Fk-1 ) F2k-1 = ( Fk ) 2 + ( Fk-1 ) 2 Ovvero: Fk-1, Fk F2k-1, F2k F0, F1 F1, F2 F3, F4 F7, F8 F15, F16 " F31, F32 F63, F64 F127, F128 F255, F256 F511, F512 F1023, F1024 … Scuola Estiva di Calcolo Avanzato Introduzione agli algoritmi Giuseppe F. Italiano fibonacci6 vs. fibonacci7 Fk+1 Fk Fk Fk-1 Fk+1 Fk = Fk Fk-1 F2k+1 F2k F2k F2k-1 8 moltiplicazioni, 4 somme + array indexing F2k = Fk ( Fk + 2 Fk-1 ) F2k-1 = ( Fk ) 2 + ( Fk-1 ) 2 3 moltiplicazioni, 2 somme, 1 shift Codice C++ 56 Scuola Estiva di Calcolo Avanzato 28 Introduzione agli algoritmi Giuseppe F. Italiano Lunghezza dell’input: |x| = log n Lunghezza dell’output: Y Tempo di esecuzione |x| Occupazione di memoria fibonacci2! O( 22 ) O(2|x| Y) fibonacci3! O( 2|x| ) O(2|x| Y) fibonacci4! O( 2|x| ) O(|x|+Y) fibonacci5! O( 2|x| ) O(|x|+Y) fibonacci6! O( |x| ) O( |x| Y ) fibonacci7! O( |x| ) O(|x|+Y) Scuola Estiva di Calcolo Avanzato 57 Introduzione agli algoritmi Giuseppe F. Italiano Tecniche algoritmiche 58 Scuola Estiva di Calcolo Avanzato 29 Introduzione agli algoritmi Giuseppe F. Italiano 1. Divide et impera 2. Programmazione dinamica 3. Greedy Scuola Estiva di Calcolo Avanzato 59 Introduzione agli algoritmi Giuseppe F. Italiano Divide et impera The control of a large force is the same principle as the control of a few men: it is merely a question of dividing up their numbers. Sun Zi, The Art of War (c. 400 C.E., VI cent. BC), translated by Lionel Giles (1910) 60 Scuola Estiva di Calcolo Avanzato 30 Introduzione agli algoritmi Giuseppe F. Italiano Divide et impera Tecnica top-down: 1. Dividi il problema in più sottoproblemi 2. Risolvi (ricorsivamente) i sottoproblemi 3. Ricombina soluzioni dei sottoproblemi per ottenere la soluzione del problema originario Esempi: ricerca binaria, mergesort, quicksort, … 61 Introduzione agli algoritmi Scuola Estiva di Calcolo Avanzato Giuseppe F. Italiano Algoritmo fibonacci6 62 Scuola Estiva di Calcolo Avanzato 31 Introduzione agli algoritmi Giuseppe F. Italiano Moltiplicazione di interi di lunghezza arbitraria Moltiplicare (o sommare) due numeri non è sempre eseguibile in tempo costante: – se i numeri occupano più di una parola di memoria, anche le operazioni elementari potrebbero richiedere tempo superiore a O(1) Moltiplicare due numeri a n cifre, con algoritmo classico (scuola elementare), richiede O(n2). Possiamo fare di meglio? Scuola Estiva di Calcolo Avanzato 63 Introduzione agli algoritmi Giuseppe F. Italiano Rappresentazione decimale di interi a n cifre • Dividiamo X e Y a metà: – X1 (Y1) = n/2 cifre più significative di X (Y) – X0 (Y0) = n/2 cifre meno significative di X (Y) 64 Scuola Estiva di Calcolo Avanzato 32 Introduzione agli algoritmi Giuseppe F. Italiano Divisione del problema 65 Scuola Estiva di Calcolo Avanzato Introduzione agli algoritmi Giuseppe F. Italiano Osservazioni • Moltiplicare un numero per 10k = shift a sinistra delle cifre del numero di k posizioni • Somma di due numeri di k cifre: tempo O(k) • La moltiplicazione di due numeri a n cifre si riduce quindi a: – quattro moltiplicazioni di numeri a n/2 cifre – un numero costante di operazioni implementabili in tempo O(k) 66 Scuola Estiva di Calcolo Avanzato 33 Introduzione agli algoritmi Giuseppe F. Italiano Relazione di ricorrenza La soluzione è Θ(n2) Cosa abbiamo guadagnato? Scuola Estiva di Calcolo Avanzato 67 Introduzione agli algoritmi Giuseppe F. Italiano Ridurre il numero di moltiplicazioni 68 Scuola Estiva di Calcolo Avanzato 34 Introduzione agli algoritmi Giuseppe F. Italiano Analisi Eseguiamo tre moltiplicazioni e un numero costante di somme e shift La soluzione è Θ(n log23 ) = Θ(n1.59) Scuola Estiva di Calcolo Avanzato 69 Introduzione agli algoritmi Giuseppe F. Italiano Idea simile per moltiplicaz. matrici A1 A2 = A3 A4 B1 B2 B3 B4 C1 C2 C3 C4 Divide et impera banale: 8 sottoproblemi n/2 x n/2 + 4 addizioni Soluzione O(n3) Divide et impera più sofisticato (Strassen 1969): 7 sottoproblemi n/2 x n/2 + O(1) addiz./sottraz. Soluzione Ο(n log27 ) = Ο(n2.81) Record di Coppersmith-Winograd Ο(n2.376) 70 Scuola Estiva di Calcolo Avanzato 35 Introduzione agli algoritmi Giuseppe F. Italiano Programmazione Dinamica The 1950s were not good years for mathematical research. We had a very interesting gentleman in Washington named Wilson. He was secretary of Defense, and he actually had a pathological fear and hatred of the word ‘research’. I’m not using the term lightly; I’m using it precisely. His face would suffuse, he would turn red, and he would get violent if people used the term ‘research’ in his presence. You can imagine how he felt, then, about the term ‘mathematical’. The RAND Corporation was employed by the Air Force, and the Air Force had Wilson as its boss, essentially. Hence, I felt I had to do something to shield Wilson and the Air Force from the fact that I was really doing mathematics inside the RAND Corporation. What title, what name, could I choose? Richard Bellman, on the origin of his term ‘dynamic programming’ (1984) Those who cannot remember the past are doomed to repeat it. George Santayana, The Life of Reason, Introduction and Reason in Common Sense (1905) Scuola Estiva di Calcolo Avanzato 71 Introduzione agli algoritmi Giuseppe F. Italiano Programmazione Dinamica! Per evitare di risolvere più volte lo stesso sottoproblema, memorizziamo la soluzione dei vari sottoproblemi: algoritmo fibonacci3(intero n) → intero sia Fib un array di n interi Fib[1] ← Fib[2] ← 1 for i = 3 to n do Fib[i] ← Fib[i-1] + Fib[i-2] return Fib[n] 72 Scuola Estiva di Calcolo Avanzato 36 Introduzione agli algoritmi Giuseppe F. Italiano Programmazione dinamica Tecnica bottom-up: 1. Identifica sottoproblemi del problema originario, procedendo logicamente dai problemi più piccoli verso quelli più grandi 2. Utilizza una tabella per memorizzare soluzioni dei sottoproblemi incontrati: quando incontri lo stesso sottoproblema, leggi la soluzione nella tabella 3. Si usa quando i sottoproblemi non sono indipendenti, (lo stesso sottoproblema può apparire più volte) Esempio: numeri di Fibonacci 73 Scuola Estiva di Calcolo Avanzato Introduzione agli algoritmi Giuseppe F. Italiano Un’applicazione di programmazione dinamica: cammini minimi Scuola Estiva di Calcolo Avanzato 37 Introduzione agli algoritmi Giuseppe F. Italiano Scuola Estiva di Calcolo Avanzato 75 Introduzione agli algoritmi Giuseppe F. Italiano Definizioni Sia G = (V,E) un grafo orientato pesato sugli archi. Il costo di un cammino π = <v0,v1,v2,… ,vk> è dato da: Un cammino minimo tra una coppia di vertici x e y è un cammino di costo minore o uguale a quello di ogni altro cammino tra gli stessi vertici. 76 Scuola Estiva di Calcolo Avanzato 38 Introduzione agli algoritmi Giuseppe F. Italiano Proprietà dei cammini minimi • Sottostruttura ottima: ogni sottocammino di un cammino minimo è anch’esso minimo • Grafi con cicli negativi: se due vertici x e y appartengono a un ciclo di costo negativo, non esiste nessun cammino minimo finito tra di essi • Se G non contiene cicli negativi, tra ogni coppia di vertici connessi in G esiste sempre un cammino minimo semplice, in cui cioè tutti i vertici sono distinti 77 Introduzione agli algoritmi Scuola Estiva di Calcolo Avanzato Giuseppe F. Italiano Distanza fra vertici • La distanza dxy tra due vertici x e y è il costo di un cammino minimo da x a y (o +∞ se i due vertici non sono connessi) • Disuguaglianza triangolare: per ogni x, y e z • Condizione di Bellman: per ogni arco (u,v) e per ogni vertice s 78 Scuola Estiva di Calcolo Avanzato 39 Introduzione agli algoritmi Giuseppe F. Italiano Algoritmo di Floyd e Warshall (per cammini minimi tra tutte le coppie, archi con costi negativi) 79 Scuola Estiva di Calcolo Avanzato Introduzione agli algoritmi Giuseppe F. Italiano Approccio • Elegante applicazione della tecnica di programmazione dinamica • Un cammino minimo k-vincolato da x a y è un cammino di costo minimo tra tutti i cammini da x a y che usano solo i vertici {v1, v2, … vk} • Idea di Floyd e Warshall: calcolare cammini minimi k-vincolati 80 Scuola Estiva di Calcolo Avanzato 40 Introduzione agli algoritmi Giuseppe F. Italiano Relazioni tra distanze vincolate k • Sia dxy il costo di un cammino minimo k-vincolato da x a y. Risulta: 0 • dxy = w(x,y) se (x,y) ∈ E, +∞ altrimenti n • dxy = dxy • L’algoritmo calcola dxy dal basso verso l’alto, incrementando k da 1 a n Scuola Estiva di Calcolo Avanzato 81 Introduzione agli algoritmi Giuseppe F. Italiano Pseudocodice Tempo di esecuzione: O(n3) 82 Scuola Estiva di Calcolo Avanzato 41 Introduzione agli algoritmi Giuseppe F. Italiano Tecnica golosa (ingorda o greedy) The point is, ladies and gentleman, greed is good. Greed works, greed is right. Greed clarifies, cuts through, and captures the essence of the evolutionary spirit. Greed in all its forms, greed for life, money, love, knowledge has marked the upward surge in mankind. And greed—mark my words—will save not only Teldar Paper but the other malfunctioning corporation called the USA. Michael Douglas as Gordon Gekko, Wall Street (1987) Scuola Estiva di Calcolo Avanzato 83 Introduzione agli algoritmi Giuseppe F. Italiano Problemi di ottimizzazione (1/2) Usata in problemi di ottimizzazione (e.g., trovare cammino più corto per andare da Napoli a Torino) Ad ogni passo, algoritmo effettua la scelta “localmente” più promettente 1. Insieme di candidati (e.g., città) 2. Insieme dei candidati già esaminati 3. Funzione ammissibile(): verifica se un insieme di candidati rappresenta una soluzione, anche non ottima (un insieme di città è un cammino da Napoli a Torino?) 84 Scuola Estiva di Calcolo Avanzato 42 Introduzione agli algoritmi Giuseppe F. Italiano Problemi di ottimizzazione (2/2) 4. Funzione ottimo(): verifica se un insieme di candidati rappresenta una soluzione ottima (un insieme di città è il più breve cammino da Napoli a Torino?) 5. Funzione seleziona(): indica quale dei candidati non ancora esaminati è al momento il più promettente 6. Funzione obiettivo da minimizzare o massimizzare (e.g., lunghezza del cammino da Napoli a Torino) 85 Introduzione agli algoritmi Scuola Estiva di Calcolo Avanzato Giuseppe F. Italiano Tecnica greedy Perché greedy? Sceglie sempre il candidato che appare più promettente! 86 Scuola Estiva di Calcolo Avanzato 43 Introduzione agli algoritmi Giuseppe F. Italiano Un’applicazione di greedy: minimi alberi ricoprenti Scuola Estiva di Calcolo Avanzato Introduzione agli algoritmi Giuseppe F. Italiano Definizioni Sia G = (V, E) un grafo connesso non orientato. Un albero ricoprente di G è un sottografo T ⊆ G tale che: – T è un albero; – T contiene tutti i vertici di G. Sia w(x,y) il costo (o peso) di un arco (x,y) ∈ E. Il costo di un albero è la somma dei costi dei suoi archi. Un minimo albero ricoprente di G è un albero ricoprente di costo minimo. 88 Scuola Estiva di Calcolo Avanzato 44 Introduzione agli algoritmi Giuseppe F. Italiano Esempi Il minimo albero ricoprente non è necessariamente unico 89 Introduzione agli algoritmi Scuola Estiva di Calcolo Avanzato Giuseppe F. Italiano Proprietà di minimi alberi ricoprenti 90 Scuola Estiva di Calcolo Avanzato 45 Introduzione agli algoritmi Giuseppe F. Italiano Tagli e cicli Dato un grafo non orientato G = (V,E), un taglio in G è una partizione dei vertici V in due insiemi: X e V-X. Un arco e = (u,v) attraversa il taglio (X,X) se u∈Xev∈X Un ciclo è un cammino in cui il primo e l’ultimo vertice coincidono 91 Introduzione agli algoritmi Scuola Estiva di Calcolo Avanzato Giuseppe F. Italiano Un approccio “greedy” • Costruiremo un minimo albero ricoprente un arco alla volta, effettuando scelte localmente “greedy”. Ad esempio: – includere nella soluzione archi di costo piccolo – escludere dalla soluzione archi di costo elevato • Formalizzeremo il processo come un processo di colorazione: – archi blu: inclusi nella soluzione – archi rossi: esclusi dalla soluzione 92 Scuola Estiva di Calcolo Avanzato 46 Introduzione agli algoritmi Giuseppe F. Italiano Regola del taglio (Regola blu) Scegli un taglio che non contiene archi blu. Tra tutti gli archi non colorati del taglio, scegline uno di costo minimo e coloralo blu. • Ogni albero ricoprente deve infatti contenere almeno un arco del taglio • E’ naturale includere quello di costo minimo Scuola Estiva di Calcolo Avanzato 93 Introduzione agli algoritmi Regola del ciclo Giuseppe F. Italiano (Regola rossa) Scegli un ciclo che non contiene archi rossi. Tra tutti gli archi non colorati del ciclo, scegline uno di costo massimo e coloralo rosso. • Ogni albero ricoprente deve infatti escludere almeno un arco del ciclo • E’ naturale escludere quello di costo massimo 94 Scuola Estiva di Calcolo Avanzato 47 Introduzione agli algoritmi Giuseppe F. Italiano L’ approccio “greedy” • L’approccio greedy applica una delle due regole ad ogni passo, finché tutti gli archi sono colorati • Si può dimostrare che esiste sempre un minimo albero ricoprente che contiene tutti gli archi blu e non contiene nessun arco rosso. • Si può inoltre dimostrare che il metodo greedy colora tutti gli archi. 95 Introduzione agli algoritmi Scuola Estiva di Calcolo Avanzato Giuseppe F. Italiano Tempi di esecuzione A seconda della scelta della regola da applicare e del taglio/ciclo usato ad ogni passo, si ottengono dal metodo greedy diversi algoritmi con diversi tempi di esecuzione 96 Scuola Estiva di Calcolo Avanzato 48 Introduzione agli algoritmi Giuseppe F. Italiano Algoritmo di Kruskal Scuola Estiva di Calcolo Avanzato 97 Introduzione agli algoritmi Giuseppe F. Italiano Strategia • Mantieni foresta di alberi blu, all’inizio tutti disgiunti • Per ogni arco, in ordine non decrescente di costo, applica il passo seguente : “se l’arco ha entrambi gli estremi nello stesso albero blu, applica regola del ciclo e coloralo rosso, altrimenti applica regola del taglio e coloralo blu” • I vertici nello stesso albero blu sono mantenuti tramite una struttura dati opportuna (union/find) 98 Scuola Estiva di Calcolo Avanzato 49 Introduzione agli algoritmi Giuseppe F. Italiano Il problema Union-find Mantenere una collezione di insiemi disgiunti di elementi distinti (interi in 1 … n) durante una sequenza delle seguenti operazioni: • union(A,B) = unisce gli insiemi A e B in un unico insieme, di nome A, e distrugge i vecchi insiemi A e B • find(x) = restituisce il nome dell’insieme contenente l’elemento x • makeSet(x) = crea il nuovo insieme {x} 99 Introduzione agli algoritmi Scuola Estiva di Calcolo Avanzato Giuseppe F. Italiano Esempio n=6 L’elemento in grassetto dà il nome all’insieme 100 Scuola Estiva di Calcolo Avanzato 50 Introduzione agli algoritmi Giuseppe F. Italiano Pseudocodice 101 Introduzione agli algoritmi Scuola Estiva di Calcolo Avanzato Giuseppe F. Italiano Esempio (1/2) 102 Scuola Estiva di Calcolo Avanzato 51 Introduzione agli algoritmi Giuseppe F. Italiano Esempio (2/2) Scuola Estiva di Calcolo Avanzato 103 Introduzione agli algoritmi Giuseppe F. Italiano Analisi Il tempo di esecuzione dell’algoritmo di Kruskal è O(m log n) nel caso peggiore (Utilizzando un algoritmo di ordinamento ottimo e la struttura dati union-find) 104 Scuola Estiva di Calcolo Avanzato 52 Introduzione agli algoritmi Giuseppe F. Italiano Riepilogo Tecniche algoritmiche: – Divide et impera: altre applicazioni nella ricerca binaria, mergesort, quicksort, moltiplicazione di matrici – Programmazione dinamica: altre applicazioni nel calcolo dei numeri di Fibonacci, associatività del prodotto tra matrici, cammini minimi tra tutte le coppie di nodi (algoritmo di Floyd e Warshall) – Tecnica greedy: altre applicazioni nel distributore automatico di resto, nel calcolo del minimo albero ricoprente (algoritmi di Prim, Kruskal, Boruvka) e dei cammini minimi (algoritmo di Dijkstra) 105 Scuola Estiva di Calcolo Avanzato 53