Sei sulla pagina 1di 82

Ingegneria degli algoritmi

Capitolo 1
Un’introduzione informale
agli algoritmi
Ingegneria degli algoritmi Giuseppe F. Italiano

Cos’è un algoritmo?
Abū Jaʿfar Muhammad ibn Mūsā al-Khwārizmī
•  Nato nell’attuale Khwarezm (Uzbekistan) ca 780
•  Autore di al-Kitāb al-mukhtaṣar fī ḥisāb al-ǧabr wa al-
muqābala (soluzioni eq. lineari 2° grado, algebra)
•  Algoritmi de numero Indorum (suo libro tradotto in
latino) introdusse notazione posizionale e numero 0 nel
mondo occidentale nel XII secolo

Francobollo commemorativo
russo del 1983 (1200 anni
dopo la sua nascita)
2
Ingegneria degli 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
Ingegneria degli 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.

Non è un algoritmo ma è un esempio di “riduzione” tra


problemi: riduce il problema di diventare milionario al
problema di ottenere un milione di dollari.
4
Ingegneria degli algoritmi Giuseppe F. Italiano

Perché studiare algoritmi?


1.  Parte centrale (core) dell’informatica

5
Ingegneria degli algoritmi Giuseppe F. Italiano

Perché studiare algoritmi?

•  Gli algoritmi sono alla base di programmi:


i.e., forniscono descrizione astratta di un
metodo (procedimento) per giungere alla
soluzione di un dato problema

6 da Demetrescu et al. Mc Graw Hill 2004


Ingegneria degli algoritmi Giuseppe F. Italiano

Perché studiare algoritmi?


1.  Parte centrale (core) dell’informatica
2.  Sempre più presenti nella nostra vita (Google,
GPS, traffico, Netflix, etc) – The Algorithms
Economy!

7
Ingegneria degli algoritmi Giuseppe F. Italiano

Un mondo basato su algoritmi

8
Ingegneria degli algoritmi Giuseppe F. Italiano

Un mondo basato su algoritmi

9
Ingegneria degli algoritmi Giuseppe F. Italiano

Un mondo basato su algoritmi

10
Ingegneria degli algoritmi Giuseppe F. Italiano

The Algorithms Economy


Ingegneria degli algoritmi Giuseppe F. Italiano

Perché studiare algoritmi?


1.  Parte centrale (core) dell’informatica
2.  Sempre più presenti nella nostra vita (Google,
GPS, traffico, Netflix, etc) – The Algorithms
Economy!
3.  Domande su algoritmi e strutture dati in
colloqui di assunzione a Microsoft, Amazon,
Facebook, Google, Yahoo etc… (e.g., http://
www.dsalgo.com/2013/02/index.php.html)
12
Ingegneria degli algoritmi Giuseppe F. Italiano

Perché studiare algoritmi?

13
Ingegneria degli algoritmi Giuseppe F. Italiano

Perché studiare algoritmi?

14
Ingegneria degli algoritmi Giuseppe F. Italiano

Perché studiare algoritmi?

Se tutto questo non vi basta ...

15
Ingegneria degli algoritmi Giuseppe F. Italiano

Perché studiare algoritmi?

16
Ingegneria degli algoritmi Giuseppe F. Italiano

Perché studiare algoritmi?

17
Ingegneria degli algoritmi Giuseppe F. Italiano

Perché studiare algoritmi?

18
Ingegneria degli algoritmi Giuseppe F. Italiano

Pseudocodice
Per mantenere massimo grado di generalità,
descriveremo algoritmi in pseudocodice:
–  ricorda linguaggi di programmazione reali
come Python, C, C++ o Java
–  può contenere alcune frasi in italiano

Traduzione in particolare linguaggio di


programmazione può essere fatta in modo
immediato e quasi meccanico
19 da Demetrescu et al. Mc Graw Hill 2004
Ingegneria degli algoritmi Giuseppe F. Italiano

Progetto ed analisi di algoritmi


Vedremo come progettare ed analizzare
algoritmi che:
–  producono correttamente risultato desiderato
–  siano efficienti in termini di tempo di
esecuzione ed occupazione di memoria

Scopo progettazione chiaro:


abbiamo bisogno di algoritmi per scrivere
un programma!
20 da Demetrescu et al. Mc Graw Hill 2004
Ingegneria degli algoritmi Giuseppe F. Italiano

Perché analizzare algoritmi?


•  Analisi teorica più affidabile di quella
sperimentale: vale su tutte le possibili istanze di
dati su cui l’algoritmo opera
•  Ci aiuta a scegliere tra diverse soluzioni allo
stesso problema
•  Permette di predire le prestazioni del software,
prima ancora di scriverne prime linee di codice

21 da Demetrescu et al. Mc Graw Hill 2004


Ingegneria degli 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)

22
Ingegneria degli 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?
23
Ingegneria degli 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
24
Ingegneria degli algoritmi Giuseppe F. Italiano

Tasso di riproduzione dei conigli


Fn : numero di coppie di conigli presenti nell’anno n
F1 = 1 (una sola coppia)
F2 = 1 (troppo giovani per procreare)
F3 = 2 (prima coppia di coniglietti)
F4 = 3 (seconda coppia di coniglietti)
F5 = 5 (prima coppia di nipotini)
Per completezza supporremo F0 = 0

25
Ingegneria degli algoritmi Giuseppe F. Italiano

I conigli di Fibonacci
Ingegneria degli algoritmi Giuseppe F. Italiano

L’albero dei conigli


La riproduzione dei conigli può quindi essere descritta da:

27
Ingegneria degli 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-1 + Fn-2 se n ≥ 3
Fn =
1 se n = 1,2

•  Problema algoritmico: come calcoliamo Fn ?


28
Ingegneria degli algoritmi Giuseppe F. Italiano

Un possibile approccio
•  Possiamo usare direttamente una soluzione alla
relazione di Fibonacci:

dove:

è la sezione aurea di un segmento


29
Ingegneria degli algoritmi Giuseppe F. Italiano

Sezione aurea

30
Ingegneria degli algoritmi Giuseppe F. Italiano

Sezione aurea

31
Ingegneria degli algoritmi Giuseppe F. Italiano

Algoritmo fibonacci1

32
Ingegneria degli 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 1.99992 2 2
16 986.698 987 987
18 2583.1 2583 2584
33
Ingegneria degli 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? recursive-fibonacci.c
34
Ingegneria degli algoritmi Giuseppe F. Italiano

Domande tipiche di questo corso


•  Quanto tempo richiede fibonacci2 ?
•  Come misuriamo il tempo?
– in secondi? (dipende da piattaforma)
– in istruzioni macchina? (dipende da
compilatore…)
•  Prima approssimazione:
– numero linee di codice mandate in esecuzione
(indipendente da piattaforma e compilatore)

35 da Demetrescu et al. Mc Graw Hill 2004


Ingegneria degli 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, una sola linea di codice
Se n = 3, 4 linee di codice:
•  2 per la chiamata fibonacci2(3)
•  1 per la chiamata fibonacci2(2)
•  1 per la chiamata fibonacci2(1)
36 da Demetrescu et al. Mc Graw Hill 2004
Ingegneria degli 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: 1 linea di codice (tempo costante);


Se n ≥ 3: 2 linee di codice più
•  chiamata a fibonacci2(n-1)
•  chiamata a fibonacci2(n-2)

37
Ingegneria degli 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:
2 + T(n-1) + T(n-2) se n ≥ 3
T(n) =
1 se n = 1, 2
A parte il 2, è come per i conigli di Fibonacci!

38 da Demetrescu et al. Mc Graw Hill 2004


Ingegneria degli 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
Come si risolvono relazioni di ricorrenza?

39 da Demetrescu et al. Mc Graw Hill 2004


Ingegneria degli algoritmi Giuseppe F. Italiano

Alberi della ricorsione


•  Utile per risolvere relazioni di ricorrenza
•  Nodi corrispondenti a chiamate ricorsive
•  Figli di un nodo corrispondenti alle sottochiamate

40
Ingegneria degli 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
41
Ingegneria degli 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

42 da Demetrescu et al. Mc Graw Hill 2004


Ingegneria degli 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)

43
Ingegneria degli 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

44
Ingegneria degli 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
45
Ingegneria degli algoritmi 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
46
Ingegneria degli 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)

47
Ingegneria degli algoritmi Giuseppe F. Italiano

Possiamo fare di meglio?


Per evitare di risolvere più volte lo stesso
sottoproblema, memorizziamo la soluzione dei
vari sottoproblemi in un array.

Fib[i] memorizza Fi

Per calcolare Fib[i] utilizziamo le soluzioni


memorizzate per Fib[i-1] e Fib[i-2]
Programmazione Dinamica
48
Ingegneria degli algoritmi Giuseppe F. Italiano

2 3 5 8 13 21 34 55 89 144
1 1

1 2 3 4 5 6 7 8 9 10 11 12

Algoritmo fibonacci3
Ingegneria degli 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]

50
Ingegneria degli algoritmi Giuseppe F. Italiano

Programmazione Dinamica
1.  Definire opportunamente sottoproblemi
(tabella)
2.  Inizializzare la tabella
3.  Dove sta la soluzione?
4.  Riempire la tabella (da condizioni iniziali a
soluzione)
Ingegneria degli algoritmi Giuseppe F. Italiano

Perché 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)

52
Ingegneria degli algoritmi Giuseppe F. Italiano

Cambiamento di prospettiva
Siamo passati da:
Those who cannot remember the past are
doomed to repeat it.
George Santayana, The Life of Reason, Introduction and Reason in
Common Sense (1905)

a:
Those who cannot forget the past are doomed
to remember it.
Jane Ace

53
Ingegneria degli algoritmi Giuseppe F. Italiano

Quanto è più veloce di fibonacci2?

array-fibonacci.c
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 ]
54
Ingegneria degli 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:

55
Ingegneria degli 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!
56
Ingegneria degli 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

iter-fibonacci.c
a←b←1
for i = 3 to n do
c ← a+b
a←b
b←c
return b
57
Ingegneria degli algoritmi Giuseppe F. Italiano

Programmazione Dinamica
1.  Definire opportunamente sottoproblemi
(tabella)
2.  Inizializzare la tabella
3.  Dove sta la soluzione?
4.  Riempire la tabella (da condizioni iniziali a
soluzione)
5.  Ci dobbiamo portare appresso tutta la tabella?
Ingegneria degli 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

59
Ingegneria degli algoritmi 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( )

60
Ingegneria degli 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

cg (n )
f(n) = Ο( g(n) )

f(n)

n0 n
61
Ingegneria degli 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) !
62
Ingegneria degli 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:
n
1 1 Fn+1 Fn
=
1 0 Fn Fn-1

•  Useremo questa proprietà per progettare un


algoritmo più efficiente di fibonacci4
63
Ingegneria degli algoritmi Giuseppe F. Italiano

Potenze ricorsive
•  Da dove deriva questa proprietà?

Fn+1 1 1 Fn
=
Fn 1 0 Fn-1

n
1 1 Fn+1 Fn
=
1 0 Fn Fn-1

64
Ingegneria degli algoritmi Giuseppe F. Italiano

Algoritmo fibonacci5

•  Tempo di esecuzione è ancora O(n)


•  Cosa abbiamo guadagnato?

65
Ingegneria degli 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 38 = (81)2 = 6561

66
Ingegneria degli 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)

67
Ingegneria degli 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, …

68
Ingegneria degli algoritmi Giuseppe F. Italiano

Algoritmo fibonacci6

69
Ingegneria degli 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?

70
Ingegneria degli 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! matrix-fibonacci.c
71
Ingegneria degli algoritmi Giuseppe F. Italiano

Riepilogo

Tempo di Occupazione di
esecuzione 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)

72
Ingegneria degli algoritmi Giuseppe F. Italiano

Lunghezza dell’input: |x| = log n


Lunghezza dell’output: Y
Tempo di Occupazione di
esecuzione memoria
2|x|
fibonacci2 O( 2 ) 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 )

73
Ingegneria degli 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…

k
1 1 Fk+1 Fk
=
1 0 Fk Fk-1

74
Ingegneria degli algoritmi Giuseppe F. Italiano

Abbiamo davvero bisogno di matrici?


Per trovare un algoritmo che non usa matrici,
concentriamoci sulla “meccanica” dei calcoli:
k
1 1 Fk+1 Fk
=
1 0 Fk Fk-1

2k
1 1 Fk+1 Fk Fk+1 Fk F2k+1 F2k
= =
1 0 Fk Fk-1 Fk Fk-1 F2k F2k-1

75
Ingegneria degli algoritmi Giuseppe F. Italiano

2k
1 1 Fk+1 Fk Fk+1 Fk F2k+1 F2k
= =
1 0 Fk Fk-1 Fk Fk-1 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
Ingegneria degli 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 è …
Ingegneria degli 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 è …
Ingegneria degli algoritmi Giuseppe F. Italiano

fibonacci6 vs. fibonacci7


Fk+1 Fk Fk+1 Fk F2k+1 F2k
=
Fk Fk-1 Fk Fk-1 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


recurrence-fibonacci.c
79
Ingegneria degli algoritmi Giuseppe F. Italiano

Lunghezza dell’input: |x| = log n


Lunghezza dell’output: Y
Tempo di Occupazione di
esecuzione memoria
2|x|
fibonacci2 O( 2 ) 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)
80
Ingegneria degli algoritmi Giuseppe F. Italiano

81
Ingegneria degli algoritmi Giuseppe F. Italiano

Cosa abbiamo imparato?


1.  Cruciale progettare algoritmi efficienti
2.  Come misurare tempo/spazio?
–  metrica indipendente da piattaforme e tecnologie
3.  In funzione di cosa esprimiamo risorse?
–  dimensione dell’input (per Fn non è n ma log n)
4.  Come confrontare algoritmi diversi?
–  stima dell’ordine di grandezza – notazione O( )
5.  Progetto/analisi richiedono strumenti matematici
–  e.g., relazioni di ricorrenza, induzione, etc…
82 da Demetrescu et al. Mc Graw Hill 2004