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