Algoritmi e Programmazione Avanzata -...
Transcript of Algoritmi e Programmazione Avanzata -...
1
1/145
Algoritmi e Programmazione Avanzata - teoria
2/145
Che cosa c’è nella lezione
Questa lezione si occupa di ricorsione e del paradigma “divide et impera”:
la ricorsione
il paradigma “divide et impera”.
2
3/145
Algoritmi e Programmazione Avanzata - teoria
4/145
Definizione
Procedura ricorsiva:
dall’interno della propria definizionechiamata alla procedura stessa(ricorsione diretta)
chiamata ad almeno una procedura la quale, direttamente o indirettamente,chiama la procedura stessa
(ricorsione indiretta)
Algoritmo ricorsivo: si basa su procedure ricorsive.
3
5/145
Definizione
La soluzione di un problema S applicato ai dati D è ricorsiva se si può esprimere come:
6/145
Definizione
La soluzione di un problema S applicato ai dati D è ricorsiva se si può esprimere come:
S(D) = f(S(D’)) D!= D0
4
7/145
Definizione
La soluzione di un problema S applicato ai dati D è ricorsiva se si può esprimere come:
S(D) = f(S(D’)) D!= D0
D’ più semplice di D
8/145
Definizione
La soluzione di un problema S applicato ai dati D è ricorsiva se si può esprimere come:
S(D) = f(S(D’)) D!= D0
S(D0) = S0
D’ più semplice di D
5
9/145
Definizione
La soluzione di un problema S applicato ai dati D è ricorsiva se si può esprimere come:
S(D) = f(S(D’)) D!= D0
S(D0) = S0
Condizione di terminazione
D’ più semplice di D
10/145
Motivazioni
Natura di molti problemi:
risoluzione di sotto-problemi analoghi a quello di partenza (ma più piccoli)Combinazione di soluzioni parziali nellasoluzione del problema originario
Eleganza matematica della soluzione.
6
11/145
Condizione di terminazione
Ogni algoritmo deve terminare⇒ ricorsione finita.
Sottoproblemi semplici e risolvibili:
banali (es.: insiemi di 1 solo elemento)
metodi alternativi alla ricorsione
12/145
Esempio: il fattoriale
n! ≡ n * (n-1)! n≥1 0! ≡ 1
7
13/145
Esempio: il fattoriale
double fact(double n){
double sub;if(n == 0)
return (1.0);else{
sub = fact(n-1);return n * sub;
}}
n! ≡ n * (n-1)! n≥1 0! ≡ 1
14/145
Esempio: il fattoriale
double fact(double n){
double sub;if(n == 0)
return (1.0);else{
sub = fact(n-1);return n * sub;
}}
Condizione di terminazione
n! ≡ n * (n-1)! n≥1 0! ≡ 1
8
15/145
Esempio: il fattoriale
double fact(double n){
double sub;if(n == 0)
return (1.0);else{
sub = fact(n-1);return n * sub;
}}
else{
sub = fact(n-1);return (n * sub);
}}
n! ≡ n * (n-1)! n≥1 0! ≡ 1
Chiamata ricorsiva
16/145
Esempio: il fattoriale
double fact(double n){
double sub;if(n == 0)
return (1.0);else{
sub = fact(n-1);return n * sub;
}}
Ricombinazione
else{
sub = fact(n-1);return (n * sub);
}}
n! ≡ n * (n-1)! n≥1 0! ≡ 1
9
17/145
Esempio: il fattoriale
5! = 5 * 4!
18/145
Esempio: il fattoriale
5! = 5 * 4!
4! = 4 * 3!
10
19/145
Esempio: il fattoriale
5! = 5 * 4!
4! = 4 * 3!
3! = 3 * 2!
20/145
Esempio: il fattoriale
5! = 5 * 4!
4! = 4 * 3!
3! = 3 * 2!
2! = 2 * 1!
11
21/145
Esempio: il fattoriale
5! = 5 * 4!
4! = 4 * 3!
3! = 3 * 2!
2! = 2 * 1!
1! = 1 * 0!
22/145
Esempio: il fattoriale
5! = 5 * 4!
4! = 4 * 3!
3! = 3 * 2!
2! = 2 * 1!
1! = 1 * 0!
0!
12
23/145
Esempio: il fattoriale
5! = 5 * 4!
4! = 4 * 3!
3! = 3 * 2!
2! = 2 * 1!
1! = 1 * 0!
0! = 1
24/145
Esempio: il fattoriale
5! = 5 * 4!
4! = 4 * 3!
3! = 3 * 2!
2! = 2 * 1!
1! = 1 * 0! = 1
0! = 1
13
25/145
Esempio: il fattoriale
5! = 5 * 4!
4! = 4 * 3!
3! = 3 * 2!
2! = 2 * 1! = 2
1! = 1 * 0! = 1
0! = 1
26/145
Esempio: il fattoriale
5! = 5 * 4!
4! = 4 * 3!
3! = 3 * 2! = 6
2! = 2 * 1! = 2
1! = 1 * 0! = 1
0! = 1
14
27/145
Esempio: il fattoriale
5! = 5 * 4!
4! = 4 * 3! = 24
3! = 3 * 2! = 6
2! = 2 * 1! = 2
1! = 1 * 0! = 1
0! = 1
28/145
Esempio: il fattoriale
5! = 5 * 4! = 120
4! = 4 * 3! = 24
3! = 3 * 2! = 6
2! = 2 * 1! = 2
1! = 1 * 0! = 1
0! = 1
15
29/145
Esempio: I numeri di Fibonacci
Calcolare l’n-esimo numero di Fibonacci
FIBn+1 = FIBn-1 + FIBn n>0FIB1 = 1FIB0 = 0
ratio aurea ϕ = (1 + √5)/2 = 1.61803ϕ’ = (1 - √5)/2 = -0.61803
FIB0 = (ϕn - ϕ’n)/ √5
30/145
Calcolo di FIB5
FIB5
16
31/145
Calcolo di FIB5
FIB5
FIB3
32/145
Calcolo di FIB5
FIB5
FIB3
FIB1
17
33/145
Calcolo di FIB5
FIB5
FIB3
FIB1
34/145
Calcolo di FIB5
FIB5
FIB3
FIB1 FIB2
18
35/145
Calcolo di FIB5
FIB5
FIB3
FIB1 FIB2
FIB0
36/145
Calcolo di FIB5
FIB5
FIB3
FIB1 FIB2
FIB0
19
37/145
Calcolo di FIB5
FIB5
FIB3
FIB1 FIB2
FIB0 FIB1
38/145
Calcolo di FIB5
FIB5
FIB3
FIB1 FIB2
FIB0 FIB1
20
39/145
Calcolo di FIB5
FIB5
FIB3
FIB1 FIB2
FIB0 FIB1
40/145
Calcolo di FIB5
FIB5
FIB3
FIB1 FIB2
FIB0 FIB1
21
41/145
Calcolo di FIB5
FIB5
FIB4FIB3
FIB1 FIB2
FIB0 FIB1
42/145
Calcolo di FIB5
FIB5
FIB4FIB3
FIB1 FIB2
FIB0 FIB1
FIB3
22
43/145
Calcolo di FIB5
FIB5
FIB4FIB3
FIB1 FIB2
FIB0 FIB1
FIB3
FIB1
44/145
Calcolo di FIB5
FIB5
FIB4FIB3
FIB1 FIB2
FIB0 FIB1
FIB3
FIB1
23
45/145
Calcolo di FIB5
FIB5
FIB4FIB3
FIB1 FIB2
FIB0 FIB1
FIB3
FIB1 FIB2
46/145
Calcolo di FIB5
FIB5
FIB4FIB3
FIB1 FIB2
FIB0 FIB1
FIB3
FIB1 FIB2
FIB0
24
47/145
Calcolo di FIB5
FIB5
FIB4FIB3
FIB1 FIB2
FIB0 FIB1
FIB3
FIB1 FIB2
FIB0
48/145
Calcolo di FIB5
FIB5
FIB4FIB3
FIB1 FIB2
FIB0 FIB1
FIB3
FIB1 FIB2
FIB0 FIB1
25
49/145
Calcolo di FIB5
FIB5
FIB4FIB3
FIB1 FIB2
FIB0 FIB1
FIB3
FIB1 FIB2
FIB0 FIB1
50/145
Calcolo di FIB5
FIB5
FIB4FIB3
FIB1 FIB2
FIB0 FIB1
FIB3
FIB1 FIB2
FIB0 FIB1
26
51/145
Calcolo di FIB5
FIB5
FIB4FIB3
FIB1 FIB2
FIB0 FIB1
FIB3
FIB1 FIB2
FIB0 FIB1
52/145
Calcolo di FIB5
FIB5
FIB4FIB3
FIB1 FIB2
FIB0 FIB1
FIB3 FIB2
FIB1 FIB2
FIB0 FIB1
27
53/145
Calcolo di FIB5
FIB5
FIB4FIB3
FIB1 FIB2
FIB0 FIB1
FIB3 FIB2
FIB1 FIB2
FIB0 FIB1
FIB0
54/145
Calcolo di FIB5
FIB5
FIB4FIB3
FIB1 FIB2
FIB0 FIB1
FIB3 FIB2
FIB1 FIB2
FIB0 FIB1
FIB0
28
55/145
Calcolo di FIB5
FIB5
FIB4FIB3
FIB1 FIB2
FIB0 FIB1
FIB3 FIB2
FIB1 FIB2
FIB0 FIB1
FIB0 FIB1
56/145
Calcolo di FIB5
FIB5
FIB4FIB3
FIB1 FIB2
FIB0 FIB1
FIB3 FIB2
FIB1 FIB2
FIB0 FIB1
FIB0 FIB1
29
57/145
Calcolo di FIB5
FIB5
FIB4FIB3
FIB1 FIB2
FIB0 FIB1
FIB3 FIB2
FIB1 FIB2
FIB0 FIB1
FIB0 FIB1
58/145
Calcolo di FIB5
FIB5
FIB4FIB3
FIB1 FIB2
FIB0 FIB1
FIB3 FIB2
FIB1 FIB2
FIB0 FIB1
FIB0 FIB1
30
59/145
Implementazione C
long fib(int n){
long f1, f2;
if(n == 0 || n == 1) return(n);
60/145
Implementazione C
long fib(int n){
long f1, f2;
if(n == 0 || n == 1) return(n);
Condizione di terminazione
31
61/145
Implementazione C
long fib(int n){
long f1, f2;
if(n == 0 || n == 1) return(n);
f1 = fib(n-1);f2 = fib(n-2);return(f1+f2);
}
Chiamate ricorsive
62/145
Implementazione C
long fib(int n){
long f1, f2;
if(n == 0 || n == 1) return(n);
f1 = fib(n-1);f2 = fib(n-2);return(f1+f2);
}
Ricombinazione
32
63/145
Esempio: ricerca binaria o dicotomica
Chiave k è presente all’interno di un vettoreordinato v[N]? Sì/No
Approccioad ogni passo: confronto k con elementocentrale:
Complessità: T(n) = O(lg n)
=: terminazione con successo<: sottovettore di SX>: sottovettore di DX
64/145
Ricerca di una chiave
1 3 4 6 8 9 11 12v
y
y<xy≥x
y = elemento di mezzo
b = indice estremo di DXa = indice estremo di SX
c = indice elemento di mezzo
4k
33
65/145
Ricerca di una chiave
1 3 4 6 8 9 11 12v
1 3 4 6 8 9 11 12
y
y<xy≥x
y = elemento di mezzo
b = indice estremo di DXa = indice estremo di SX
c = indice elemento di mezzo
4k
66/145
Ricerca di una chiave
1 3 4 6 8 9 11 12v
1 3 4 6 8 9 11 12
y
y<xy≥x
y = elemento di mezzo
b = indice estremo di DXa = indice estremo di SX
c = indice elemento di mezzo
4k
34
67/145
Ricerca di una chiave
1 3 4 6 8 9 11 12v
1 3 4 6 8 9 11 12
1 3 4 6 y
y<xy≥x
y = elemento di mezzo
b = indice estremo di DXa = indice estremo di SX
c = indice elemento di mezzo
4k
68/145
Ricerca di una chiave
1 3 4 6 8 9 11 12v
1 3 4 6 8 9 11 12
1 3 4 6 y
y<xy≥x
y = elemento di mezzo
b = indice estremo di DXa = indice estremo di SX
c = indice elemento di mezzo
4k
35
69/145
Ricerca di una chiave
1 3 4 6 8 9 11 12v
1 3 4 6 8 9 11 12
1 3 4 6
4 6
y
y<xy≥x
y = elemento di mezzo
b = indice estremo di DXa = indice estremo di SX
c = indice elemento di mezzo
4k
70/145
Ricerca di una chiave
1 3 4 6 8 9 11 12v
1 3 4 6 8 9 11 12
1 3 4 6
4 6
y
y<xy≥x
y = elemento di mezzo
b = indice estremo di DXa = indice estremo di SX
c = indice elemento di mezzo
4k
36
71/145
Ricerca di una chiave
1 3 4 6 8 9 11 12v4k
1 3 4 6 8 9 11 12
1 3 4 6
4 6
y
y<xy≥x
y = elemento di mezzo
b = indice estremo di DXa = indice estremo di SX
c = indice elemento di mezzo
Trovato!
72/145
Implementazione C
int RicBin(int v[], int a, int b, int k){
int c;if(b-a == 0)
if(v[a]==k) return(a);else return(–1);
37
73/145
Implementazione C
int RicBin(int v[], int a, int b, int k){
int c;if(b-a == 0)
if(v[a]==k) return(a);else return(–1);
Condizione di terminazione
74/145
Implementazione C
int RicBin(int v[], int a, int b, int k){
int c;if(b-a == 0)
if(v[a]==k) return(a);else return(–1);
c = (a+b) / 2;if(v[c] >= k)
return(RicBin(v, a, c, k));else return(RicBin(v, c+1, b, k));
}Chiamate ricorsive
38
75/145
Dualità ricorsione - iterazione
Ogni programma ricorsivo può ancheessere implementato in modo iterativo.
La soluzione migliore (efficienza e chiarezzadel codice) dipende dal problema.
76/145
Esempio: fattoriale iterativo
5! = 1*2*3*4*5
= 120
double fact(double n){
double tot = 1.0;int i;for(i=2; i<=n; ++i)
tot = tot * i;return(tot);
}
39
77/145
Esempio: Fibonacci iterativo
FIB5:
FIB0 = 0FIB1 = 1FIB2 = FIB0 + FIB1 = 1FIB3 = FIB1 + FIB2 = 2FIB4 = FIB2 + FIB3 = 3FIB5 = FIB3 + FIB4 = 5
long fib(int n){long f1p=1, f2p=0, f;int i;if(n == 0 || n == 1) return(n);f = f1p + f2p; /* n==2 */for(i=3; i<= n; ++i)
{ f2p = f1p;f1p = f;f = f1p+f2p;
}return(f);
}
78/145
Esempio: ricerca binaria iterativa
int RicBin(int v[], int a, int b, int k){
int c;while(b-a != 0){
c = (a+b) / 2;if(v[c] >= k)
b = c;else a = c+1;
}if(v[a]==k) return(a);else return(–1);
}
40
79/145
Esempio: ricerca binaria iterativa
1 3 4 6 8 9 11 12v
b = indice estremo di DXa = indice estremo di SX
a b4k
80/145
Esempio: ricerca binaria iterativa
1 3 4 6 8 9 11 12v
b = indice estremo di DXa = indice estremo di SX
c = indice elemento dimezzo
a bc4k
41
81/145
Esempio: ricerca binaria iterativa
1 3 4 6 8 9 11 12v
1 3 4 6 8 9 11 12va b
b = indice estremo di DXa = indice estremo di SX
c = indice elemento dimezzo
a bc4k
82/145
Esempio: ricerca binaria iterativa
1 3 4 6 8 9 11 12v
1 3 4 6 8 9 11 12vc
b = indice estremo di DXa = indice estremo di SX
c = indice elemento dimezzo
a bc4k
a b
42
83/145
Esempio: ricerca binaria iterativa
1 3 4 6 8 9 11 12v
1 3 4 6 8 9 11 12v
1 3 4 6 8 9 11 12va b
b = indice estremo di DXa = indice estremo di SX
c = indice elemento dimezzo
a bc4k
ca b
84/145
Esempio: ricerca binaria iterativa
1 3 4 6 8 9 11 12v
1 3 4 6 8 9 11 12v
1 3 4 6 8 9 11 12v
c
b = indice estremo di DXa = indice estremo di SX
c = indice elemento dimezzo
a bc4k
a b
ca b
43
85/145
Esempio: ricerca binaria iterativa
1 3 4 6 8 9 11 12v
1 3 4 6 8 9 11 12v
1 3 4 6 8 9 11 12v
1 3 4 6 8 9 11 12vab
b = indice estremo di DXa = indice estremo di SX
c = indice elemento dimezzo
a bc4k
ca b
ca b
86/145
Esempio: ricerca binaria iterativa
1 3 4 6 8 9 11 12va b
1 3 4 6 8 9 11 12v
1 3 4 6 8 9 11 12v
1 3 4 6 8 9 11 12vabc
b = indice estremo di DXa = indice estremo di SX
c = indice elemento dimezzo
c4k
ca b
ca b
44
87/145
Esempio: ricerca binaria iterativa
1 3 4 6 8 9 11 12v 4ka b
1 3 4 6 8 9 11 12v
1 3 4 6 8 9 11 12v
1 3 4 6 8 9 11 12vabc
b = indice estremo di DXa = indice estremo di SX
c = indice elemento dimezzo
c
Trovato!
ca b
ca b
88/145
Algoritmi e Programmazione Avanzata - teoria
45
89/145
DivideDa problema di dimensione n aproblemi indipendenti di dimensione n/b.
ImperaRisoluzione di problema elementare.
CombinaRicostruzione di soluzione complessiva
combinando le soluzioni parziali.
Implementazione ricorsiva.
Divide et Impera 1/2
90/145
Risolvi(Problema):
Se il problema è elementare:
- Soluzione = Risolvi_banale(Problema)
Divide et Impera 2/2
46
91/145
Risolvi(Problema):
Se il problema è elementare:
- Soluzione = Risolvi_banale(Problema)
Condizione di terminazione
Divide et Impera 2/2
92/145
Risolvi(Problema):
Se il problema è elementare:
- Soluzione = Risolvi_banale(Problema)
Altrimenti:- Sottoproblema1,2,3,…,a = Dividi(Problema) ;
Divide et Impera 2/2
47
93/145
Risolvi(Problema):
Se il problema è elementare:
- Soluzione = Risolvi_banale(Problema)
Altrimenti:- Sottoproblema1,2,3,…,a = Dividi(Problema) ;
“a” sottoproblemi, ciascuno “b” volte
più piccolo del problema
Divide et Impera 2/2
94/145
Risolvi(Problema):
Se il problema è elementare:
- Soluzione = Risolvi_banale(Problema)
Altrimenti:- Sottoproblema1,2,3,…,a = Dividi(Problema) ;
- Per ciascun Sottoproblemai:-- Sottosoluzionei = Risolvi(Sottoproblemai) ;
Divide et Impera 2/2
48
95/145
Divide et Impera 2/2
Risolvi(Problema):
Se il problema è elementare:
- Soluzione = Risolvi_banale(Problema)
Altrimenti:- Sottoproblema1,2,3,…,a = Dividi(Problema) ;
- Per ciascun Sottoproblemai:-- Sottosoluzionei = Risolvi(Sottoproblemai) ;
Chiamata ricorsiva
96/145
Complessità 1/3
Equazione alle Ricorrenze:
T(n) in termini del tempo di esecuzione per input più piccoli.
49
97/145
Complessità 2/3
T(n) = D(n) + a T(n/b) + C(n) n > cT(n) = Θ(1) n ≤ c
D(n): costo della divisionea: numero di sottoproblemi che risulta dallafase di Dividen/b: dimensione di ciascun sottoproblemaC(n): costo della ricombinazioneΘ(1): costo della soluzione elementare.
98/145
Risolvi(Problema):
Complessità 3/3
50
99/145
Risolvi(Problema):
Complessità 3/3T(n)
100/145
Risolvi(Problema):
Se il problema è elementare:- Soluzione = Risolvi_banale(Problema)
Complessità 3/3
51
101/145
Risolvi(Problema):
Se il problema è elementare:- Soluzione = Risolvi_banale(Problema)
Complessità 3/3
Θ(1)
102/145
Risolvi(Problema):
Se il problema è elementare:- Soluzione = Risolvi_banale(Problema)
Altrimenti:- Sottoproblema1,2,3,…,a = Dividi(Problema);
Complessità 3/3
52
103/145
Risolvi(Problema):
Se il problema è elementare:- Soluzione = Risolvi_banale(Problema)
Altrimenti:- Sottoproblema1,2,3,…,a = Dividi(Problema);
Complessità 3/3
D(n)
104/145
Risolvi(Problema):
Se il problema è elementare:- Soluzione = Risolvi_banale(Problema)
Altrimenti:- Sottoproblema1,2,3,…,a = Dividi(Problema);- Per ciascun Sottoproblema i:
Complessità 3/3
53
105/145
Risolvi(Problema):
Se il problema è elementare:- Soluzione = Risolvi_banale(Problema)
Altrimenti:- Sottoproblema1,2,3,…,a = Dividi(Problema);- Per ciascun Sottoproblema i:
Complessità 3/3
a sottoproblemi
106/145
Risolvi(Problema):
Se il problema è elementare:- Soluzione = Risolvi_banale(Problema)
Altrimenti:- Sottoproblema1,2,3,…,a = Dividi(Problema);- Per ciascun Sottoproblema i:
-- Sottosoluzione i = Risolvi(Sottoproblema i);
Complessità 3/3
54
107/145
Risolvi(Problema):
Se il problema è elementare:- Soluzione = Risolvi_banale(Problema)
Altrimenti:- Sottoproblema1,2,3,…,a = Dividi(Problema);- Per ciascun Sottoproblema i:
-- Sottosoluzione i = Risolvi(Sottoproblema i);
Complessità 3/3
T(n/b)
108/145
Risolvi(Problema):
Se il problema è elementare:- Soluzione = Risolvi_banale(Problema)
Altrimenti:- Sottoproblema1,2,3,…,a = Dividi(Problema);- Per ciascun Sottoproblema i:
-- Sottosoluzione i = Risolvi(Sottoproblema i);
- Return Soluzione- Combina(Sottosoluzione1,2,3,…,a);
Complessità 3/3
55
109/145
Risolvi(Problema):
Se il problema è elementare:- Soluzione = Risolvi_banale(Problema)
Altrimenti:- Sottoproblema1,2,3,…,a = Dividi(Problema);- Per ciascun Sottoproblema i:
-- Sottosoluzione i = Risolvi(Sottoproblema i);
- Return Soluzione- Combina(Sottosoluzione1,2,3,…,a);
Complessità 3/3
C(n)
110/145
Esempio
Ricerca binariaD(n) = Θ(1), C(n) = Θ(1)a = 1, b = 2
T(n) = T(n/2) + 1 n > 1T(n) = 1 n = 1
56
111/145
Esempio
A ogni passo la dimensione si dimezza
All’i-esimo passo è n/2i
Numero di passi: n/2i =1 i= log2n
ciascuno di costo costanteT(n) = O(lg n)
112/145
Esempio
A ogni passo la dimensione si dimezza
All’i-esimo passo è n/2i
Numero di passi: n/2i =1 i= log2n
ciascuno di costo costanteT(n) = O(lg n)
57
113/145
Esempio
A ogni passo la dimensione si dimezza
All’i-esimo passo è n/2i
Numero di passi: n/2i =1 i= log2n
ciascuno di costo costanteT(n) = O(lg n)
114/145
Esempio
A ogni passo la dimensione si dimezza
All’i-esimo passo è n/2i
Numero di passi: n/2i =1 i= log2n
ciascuno di costo costanteT(n) = O(lg n)
58
115/145
Esempio
A ogni passo la dimensione si dimezza
All’i-esimo passo è n/2i
Numero di passi: n/2i =1 i= log2n
ciascuno di costo costanteT(n) = O(lg n)
116/145
Limiti
Ipotesi di indipendenza dei sottoproblemiMemoria occupata
FIB5
FIB4FIB3
FIB1 FIB2
FIB0 FIB1
FIB3 FIB2
FIB1 FIB2
FIB0 FIB1
FIB0 FIB1
59
117/145
Limiti
Ipotesi di indipendenza dei sottoproblemiMemoria occupata
FIB5
FIB4FIB3
FIB1 FIB2
FIB0 FIB1
FIB3 FIB2
FIB1 FIB2
FIB0 FIB1
FIB0 FIB1
FIB5
FIB4
FIB3
FIB2
FIB1 FIB0
118/145
Le Torri di Hanoi
Configurazione iniziale: vi sono 3 pioli, 3 dischi di diametrodecrescente sul primo piolo
Configurazione finale: 3 dischi sul terzo piolo
Regole:accesso solo al disco in cimasopra ogni disco solo dischi più piccoli
Generalizzabile a n dischi e k pioli.
60
119/145
Esempio di soluzione
0 1 2
120/145
Esempio di soluzione
0 1 2
0 2
61
121/145
Esempio di soluzione
0 1 2
0 20 1 2
122/145
Esempio di soluzione
0 1 2
0 2 0 10 1 2
62
123/145
Esempio di soluzione
0 1 2
0 2 0 1
0 1 2
0 1 2
124/145
Esempio di soluzione
0 1 2
0 2 0 1
2 10 1 2
0 1 2
63
125/145
Esempio di soluzione
0 1 2
0 2 0 1
2 10 1 2
0 1 2
0 1 2
126/145
Esempio di soluzione
0 1 2
0 2 0 1
2 1 0 20 1 2
0 1 2
0 1 2
64
127/145
Esempio di soluzione
0 1 2
0 2 0 1
2 1 0 20 1 2
0 1 2
0 1 2
0 1 2
128/145
Esempio di soluzione
0 1 2
0 2 0 1
2 1 0 2
1 0
0 1 2
0 1 2
0 1 2
0 1 2
65
129/145
Esempio di soluzione
0 1 2
0 2 0 1
2 1 0 2
1 0
0 1 2
0 1 2
0 1 2
0 1 2
0 1 2
130/145
Esempio di soluzione
0 1 2
0 2 0 1
2 1 0 2
1 0 1 2
0 1 2
0 1 2
0 1 2
0 1 2
0 1 2
66
131/145
Esempio di soluzione
0 1 2
0 2 0 1
2 1 0 2
1 0 1 2
0 1 2
0 1 2
0 1 2
0 1 2
0 1 2
0 1 2
132/145
Esempio di soluzione
0 1 2
0 2 0 1
2 1 0 2
1 0 1 2
0 2
0 1 2
0 1 2
0 1 2
0 1 2
0 1 2
0 1 2
67
133/145
Esempio di soluzione
0 1 2
0 2 0 1
2 1 0 2
1 0 1 2
0 2
0 1 2
0 1 2
0 1 2
0 1 2
0 1 2
0 1 2
0 1 2
134/145
Strategia divide et impera 1/3
Problema iniziale: spostare n dischi da 0 a 2
Riduzione a sottoproblemi:n-1 dischi da 0 a 1, 2 depositol’ultimo disco da 0 a 2n-1 dischi da 1 a 2, 0 deposito
Condizione di terminazione: si muove 1 solo disco.
68
135/145
Strategia divide et impera 2/3
0, 1, 2: piolo 0, 1, 2g disco grandeg disco mediog disco piccolo0 significa disco piccolo su piolo 0,2 significa disco grande su piolo 2, etc.statotransizione di stato
011
136/145
Strategia divide et impera 3/3
Problema da decomposto in 3sottoproblemi:
Dischi medio e piccolo da 0 a 1
Disco grande da 0 a 2
Dischi medio e piccolo da 1 a 2
000 222
000 011
011 211
211 222
69
137/145
Albero della ricorsione
000 222
000 011 011 211 211 222
000 002 002 012 012 011 211 210 210 220 220 222
138/145
Implementazione C
void Hanoi(int *mossa,int n,int src,int dest)
70
139/145
Implementazione C
void Hanoi(int *mossa,int n,int src,int dest)Numero dischi
140/145
Implementazione C
void Hanoi(int *mossa,int n,int src,int dest)
Piolo di partenza
71
141/145
Implementazione C
void Hanoi(int *mossa,int n,int src,int dest)
Piolo di arrivo
142/145
Implementazione C
void Hanoi(int *mossa,int n,int src,int dest){int aux;
Deposito
72
143/145
Implementazione C
void Hanoi(int *mossa,int n,int src,int dest){int aux;if (n > 0) {aux = 3 - (src + dest);Hanoi(mossa, n-1, src, aux);fprintf (stdout,"(%d) src %d -> dest %d \n",
*mossa, src, dest);*mossa = *mossa + 1;Hanoi(mossa, n-1, aux, dest);
}return;}
144/145
Complessità 1/2
Dividi: considera n-1 dischiD(n)=Θ(1)
Risolvi: risolve 2 sottoproblemi di dimensionen-1 ciascuno
2T(n-1)
Terminazione: spostamento di 1 discoΘ(1)
Combina: nessuna azioneC(n) = Θ(1)
73
145/145
Complessità 2/2
Equazione alle ricorrenze:
T(n) = 2T(n-1) + 1 n>1T(1) = 1
T(n) = Σn-1i=0 2i = (1+2+4+ …) = 2n –1