2. Riferimenti
•
•
2
Bertossi Alan A., Montresor Alberto. ―Algoritmi e
strutture di dati‖ (seconda edizione), CittàStudi 2010
Stanley B. Lippman, Barbara E. Moo, Josee Lajoie
―C++ Primer‖, 5th Edition Addison-Wesley
Prof. Pier Luca Lanzi
3. ― As soon as an Analytic Engine exists, it will
necessarily guide the future course of the
science. Whenever any result is sought by its
aid, the question will arise—By what course of
calculation can these results be arrived at by
the machine in the shortest time?‖ - Charles
Babbage (1864)
Prof. Pier Luca Lanzi
4. Esempio: Ordinamento di un Vettore
•
•
4
Definizione del Problema
Input: sequenza a1, a2, …, an di numeri.
Output: permutazione a'1, a'2, …, a'n che soddisfi
la relazione a'1 a'2 … a'n
Esempio
Input: 8 2 4 9 3 6
Output: 2 3 4 6 8 9
Prof. Pier Luca Lanzi
5. Algoritmo di Insertion Sort
(pseudo codice)
5
insertionSort(array A)
for i ← 1 to length[A]-1 do
value ← A[i]
j ← i-1
while j >= 0 and A[j] > value do
A[j + 1] ← A[j]
j ← j-1
A[j+1] ← value
0
i
j
A:
key
sorted
http://ideone.com/3Sn5m
Prof. Pier Luca Lanzi
n-1
6. Insertion Sort: Animazione da Wikipedia
Animazione dell’Insertion Sort da Wikipedia
http://en.wikipedia.org/wiki/Insertion_sort
http://en.wikipedia.org/wiki/Image:Insertion_sort_animation.gif
Prof. Pier Luca Lanzi
6
18. Tempo di Esecuzione
•
•
•
18
Dipende dall’input
Dal numero di elementi
Dallo stato del vettore, una sequenza già ordinata
richiede meno tempo
Calcolare il tempo di esecuzione parametrizzandolo
rispetto al numero di elementi di input (vettori più piccoli
richiedono meno tempo)
Cerchiamo limiti superiori al tempo di esecuzione dato che
danno una garanzia sul tempo massimo richiesto
Prof. Pier Luca Lanzi
19. Quale Definizione di Tempo?
•
•
•
19
Tempo = ―Wall-clock‖ time:
Il tempo effettivamente impiegato per eseguire un
algoritmo
Dipende da troppi parametri:
bravura del programmatore
linguaggio di programmazione utilizzato
codice generato dal compilatore
processore, memoria (cache, primaria, secondaria)
sistema operativo, processi attualmente in esecuzione
Dobbiamo considerare un modello astratto, che possiamo
derivare empiricamente o analiticamente
Prof. Pier Luca Lanzi
21. Analisi Empirica del
Tempo di Esecuzione
•
•
•
21
Instrumentare il codice con le istruzioni per la rilevazione
del tempo trascorso
Eseguire il codice con dati di input di diverse dimensioni
(eventualmente piu’ volte per la stessa dimensione)
Analisi dei dati raccolti
Prof. Pier Luca Lanzi
22. Instrumentare il Codice:
Insertion Sort
22
clock_t begin=clock();
for(int i=1; i<=n-1; i++)
{
int value = A[i];
int j = i-1;
while ( (j>=0) && (A[j]>value) ) {
A[j+1] = A[j];
j = j-1;
}
A[j+1] = value;
}
clock_t end=clock();
// stampa i millisecondi
std::cout << double(end-begin)*1000/CLOCKS_PER_SEC << std::endl;
// http://ideone.com/UuX1d
Prof. Pier Luca Lanzi
23. Raccolta Dati & Analisi
N
T(N)
1000
2000
4000
8000
16000
32000
64000
5.769
15.316
63.204
244.228
988.69
3908.8
15949
Prof. Pier Luca Lanzi
23
24. Analisi Dati
•
•
24
Considerare il grafico utilizzando le scale logaritmiche sia
per l’ascissa che l’ordinata
Interpolare i punti ottenuti
assumendo una relazione
lineare
log2(T(N)) = blog2(N)+c
•
Ottenendo
T(N) = aNb dove a=2c
Prof. Pier Luca Lanzi
25. Metodo per Ottenere una Stima di b
•
Eseguire il programma raddoppiando la grandezza
dell’input
N
T(N)
Ratio
1000
5.77
2000
15.32
2.65
4000
63.20
4.13
8000 244.23 3.86
16000 988.69 4.05
32000 3908.80 3.95
15949.0
64000
0
4.08
•
•
25
Log(Ratio)
1.41
2.04
1.95
2.02
1.98
converge a ~2
2.03
Ipotizzando che il tempo di esecuzione abbia sia aNb
allora,
b e’ puo’ essere calcolato come il log2 del ratio
Prof. Pier Luca Lanzi
In questo caso possiamo assumere che b sia 2
26. Metodo per Ottenere una Stima di a
•
•
Assumendo di conoscere b, si puo’ ricavare a, misurando
il tempo di esecuzione per un N abbastanza grande
Ad esempio, con b=2,
974.36 = aN2
•
26
Si ricava, otteniamo a = .38x10-5
Prof. Pier Luca Lanzi
N
T(N)
16000
16000
16000
988.7
967.1
967.3
28. Quale Definizione di Tempo?
•
•
•
28
Tempo = ―numero operazioni elementari‖
Quali operazioni possono essere considerate elementari?
Moltiplicazioni, assegnamenti elementari, ecc.
Possiamo considerare il calcolo del minimo di un
vettore di n elementi un’operazione elementare?
Modello di calcolo
Rappresentazione astratta di un esecutore (il
calcolatore)
L’astrazione elimina i dettagli inutili
Il modello computazionale deve riflettere la situazione
reale
Prof. Pier Luca Lanzi
Deve permettere di trarre conclusioni ―formali‖ sul
29. Esempio: Elemento Minimo di un Vettore
int minimo(std::vector<int> A)
// costo
{
int m = A[0];
// c1
1
int i;
for(i=1; i<A.size(); i++)
// c2
if (m>A[i])
// c3
m = A[i];
// c1
return m;
// c4
29
# esecuzioni
n
n-1
n-1
1
}
•
•
•
Ogni istruzione richiede un tempo costante per essere eseguita
Costante diversa da istruzione a istruzione
Ogni istruzione viene eseguita un certo # di volte, dipendente da n
•
T(n) = c1+ n*c2 + (n-1)*c3 + (n-1)*c1 + c4 = a*n+b
Prof. Pier Luca Lanzi
30. Esempio: Ricerca Binaria Ricorsiva
bool recursive_binary_find(std::vector<int> A, int lower, int upper, int x)
{
// costo # esecuzioni
if (upper<lower) return false;
c1
1
int m = (lower+upper)/2;
c2
1
if (x==A[m]) return true;
c1
1
if (x>A[m])
c3
1
return recursive_binary_find(A, m+1, upper, x); T(n/2)
else return recursive_binary_find(A,lower, m-1, x); T(n/2)
1
1
} // http://ideone.com/AH7Dg
•
T(n) = c1 + c2 + c1 + c3 + T(n/2) = T(n/2) + d se n>1
•
T(n) = c1 altrimenti
Prof. Pier Luca Lanzi
30
31. Calcolo T(n) per la Ricerca
Binaria Ricorsiva
•
•
31
Assunzioni
Per semplicità, n =2k è una potenza di 2
L’elemento cercato non è presente (caso pessimo)
Ad ogni suddivisione, scegliamo sempre la parte destra
di dimensione n/2 (caso pessimo)
Equazione alle ricorrenze
Prof. Pier Luca Lanzi
32. Calcolo T(n) per la Ricerca
Binaria Ricorsiva
Prof. Pier Luca Lanzi
32
33. Quale Tipo di Analisi?
•
•
•
33
Caso Pessimo (worst-case): (tipico)
T(n) tempo massimo per un input di n elementi
Caso Medio (average-case): (raramente disponibile)
T(n) tempo medio per un input di n elementi
Problema: Qual è la distribuzione degli input?
Caso Migliore (best-case): (non informativo)
Algoritmi lenti possono essere molto veloci in casi
particolarmente favorevoli
Non considerare una particolare macchina
Analisi Asintotica - Studiare T(n) per n → ∞
Prof. Pier Luca Lanzi
35. Quanto guadagno se compero
un calcolatore 10 volte più veloce?
Vecchio PC in un tempo T
esegue 104 istruzioni
Prof. Pier Luca Lanzi
Nuovo PC 10 volte più veloce
in T esegue 105 istruzioni
36. T
104
# istruzioni
algoritmo 10n
nV=104/10=1000
105
nN=10000
In termini di capacità di calcolo
il guadagno è nN/nV = 10
Con un algoritmo di complessità lineare
l’aumento di potenza di calcolo si è trasferito nell’effettiva
capacità di elaborazione
Prof. Pier Luca Lanzi
37. T
# istruzioni
104
105
algoritmo 10n
nV=103
nN=104
nN/nV =10
algoritmo 20n
nV=500
nN=5000
nN/nV =10
algoritmo 5nlogn
nV=250
nN=1843
nN/nV =7.3
Con un algoritmo 5nlogn l’aumento di velocità si è solo
parzialmente trasferito in capacità di elaborazione
Il calcolatore è 10 volte più veloce ma elabora
solo un numero di dati che è solo 7.3 volte più grande
Prof. Pier Luca Lanzi
38. T
104
# istruzioni
algoritmo 10n
algoritmo 20n
algoritmo 5nlog n
algoritmo 2n2
algoritmo 2n
105
nV=103
nV=500
nV=250
nV=70
nV=13
nN=104
nN=5000
nN=1843
nN=223
nN=16
Aumentando la complessità dell’algoritmo,
il vantaggio diventa irrisorio come nel caso 2n
Prof. Pier Luca Lanzi
nN/nV =10
nN/nV =10
nN/nV =7.3
nN/nV =3.2
nN/nV =1.2
39. Per a, b > 1 qualsiasi
na cresce più velocemente di logb n
(meglio logaritmico che polinomiale)
na cresce più velocemente di log nb
(meglio potenza di un logaritmo che un polinomio)
an cresce più velocemente nb
(meglio polinomiale che esponenziale)
Prof. Pier Luca Lanzi
40. Analisi Asintotica: Notazione O-grande
•
•
40
Definizione: sia T(n) una funzione non-negativa,
T(n) è O(f(n)) se esistono due costanti positive c ed n0 tali che T(n) <=
cf(n) per ogni n> n0
Per tutti i gli insiemi di dati di input grandi a sufficienza,
(n>n0), l’algoritmo termina la sua esecuzione in meno di cf(n) passi
(nel caso migliore, medio, o peggiore).
•
La notazione O-grande indica un limite superiore a T(n)
•
Esempio: se T(n) = 3n2 allora T(n) è in O(n2)
•
Ovviamente siamo interessati al minimo limite superiore,
se T(n) = 3n2 è O(n3), ma preferiamo O(n2)
Prof. Pier Luca Lanzi
41. Analisi Asintotica: Notazione Ω-grande
•
•
41
Definizione: sia T(n) una funzione non-negativa,
T(n) è Ω(g(n)) se esistono due costanti positive c ed n0 tali che T(n)
>= cg(n) per ogni n> n0
Per tutti i gli insiemi di dati di input grandi a sufficienza,
(n>n0), l’algoritmo ha bisogno almeno di cg(n) passi (nel caso
migliore, medio, o peggiore).
•
La notazione Ω-grande indica un limite inferiore a T(n)
•
Esempio: se T(n) = 2n2+n allora T(n) è in Ω(n2)
•
Ovviamente siamo interessati al massimo limite inferiore,
T(n) = 2n2+n è Ω(n), ma preferiamo Ω(n2)
Prof. Pier Luca Lanzi
42. Analisi Asintotica: Notazione Θ-grande
•
•
42
Definizione: se T(n) è Ω(h(n)) e anche O(h(n)) allora
T(n) è Θ(h(n))
Ovvero, se esistono due costanti c1 e c2, ed n0 tali che
c1g(n) ≤ f(n) ≤ c2g(n) per ogni n>n0
Prof. Pier Luca Lanzi
43. Analisi Asintotica
43
Per n grande, un algoritmo Θ(n2) è sempre
più veloce di un algoritmo Θ (n3)
•
•
•
T(n)
•
n
n0
Prof. Pier Luca Lanzi
Vero asintoticamente!
Non ignorare gli algoritmi che
sono asintoticamente lenti
Nelle situazioni reali bisogna
spesso bilanciare obiettivi
contrapposti
Tipico esempio, performance vs.
complessità
46. Regole di Semplificazione
46
•
Se f(n) è O(g(n)) e g(n) è O(h(n)), allora f(n) è O(h(n))
•
Se f(n) è O(kg(n)) per ogni k>0, allora f(n) è O(g(n))
•
•
•
Se f1(n) è O(g1(n)) ed f2(n) è O(g2(n)),
allora (f1 + f2)(n) è O(max(g1(n), g2(n)))
Se f1(n) è O(g1(n)) ed f2(n) è O(g2(n)),
allora f1(n)f2(n) è O(g1(n)g2(n))
In breve, eliminare i termini di ordine inferiore,
ignorare le costanti.
Prof. Pier Luca Lanzi
47. Limitazioni Inferiori e Algoritmi Ottimi
•
•
•
47
Dato un problema, se troviamo un algoritmo A con complessità
O(g(n)), avete stabilito un limite superiore alla complessità del
problema - g(n)
Se dimostrate che qualunque algoritmo per il problema deve avere
complessità Ω(f(n)), avete stabilito un limite inferiore all complessità
del problema - f(n)
Se f(n)=g(n), allora A è un algoritmo ottimo
Prof. Pier Luca Lanzi
48. Esempi di Analisi Asintotica
•
Esempio 1:
a = b;
•
Esempio 2:
sum = 0;
for (i=1; i<=n; i++)
sum += n;
Prof. Pier Luca Lanzi
49. Esempi di Analisi Asintotica
•
Esempio 3:
sum = 0;
for (i=1; i<=n; i++)
for (j=1; j<=i; j++)
sum++;
for (k=0; k<n; k++)
A[k] = k;
Prof. Pier Luca Lanzi
49
50. Esempi di Analisi Asintotica
•
Esempio 4:
sum1 = 0;
for (i=1; i<=n; i++)
for (j=1; j<=n; j++)
sum1++;
sum2 = 0;
for (i=1; i<=n; i++)
for (j=1; j<=i; j++)
sum2++;
Prof. Pier Luca Lanzi
50
51. Esempi di Analisi Asintotica
•
Esempio 5:
sum1 = 0;
for (k=1; k<=n; k*=2)
for (j=1; j<=n; j++)
sum1++;
sum2 = 0;
for (k=1; k<=n; k*=2)
for (j=1; j<=k; j++)
sum2++;
Prof. Pier Luca Lanzi
51
52. Strutture di Controllo
52
•
Istruzione while: viene analizzato come il ciclo for
•
Istruzione if: complessità del blocco più costoso
•
Istruzione switch: complessità del caso più costoso
•
Chiamata a subroutine: complessità della subroutine
•
Passaggio dei parametri:
Tipi semplici, il costo è una costante
Vettori o strutture, se passati per indirizzo,
il passaggio ha un costo costante
Altrimenti, il costo è quello della copia
Prof. Pier Luca Lanzi
53. Qual è la Complessità Insertion Sort?
insertionSort(array A)
for i ← 1 to length[A]-1 do
value ← A[i]
j ← i-1
while j >= 0 and A[j] > value do
A[j + 1] ← A[j]
j ← j-1
A[j+1] ← value
Prof. Pier Luca Lanzi
53
54. Qual è la Complessità Insertion Sort?
void insertion_sort(std::vector<int> &A)
{
int i;
int j;
int value;
for(i=1; i<A.size(); i++)
{
value = A[i];
j = i-1;
while(j>=0 && A[j]>value)
{
A[j+1] = A[j];
j = j-1;
}
A[j+1] = value;
}
} // http://ideone.com/siE9V
Prof. Pier Luca Lanzi
54
55. Analisi Asintotica dell’Insertion Sort
•
55
Caso Peggiore:
n
T(n)
( j)
n2
j 2
•
Caso Medio: (tutte le possibili permutazioni siano equiprobabili)
T(n)
n
( j / 2)
n2
j 2
•
È un algoritmo veloce?
Si, per n piccoli
No, per n grandi
Prof. Pier Luca Lanzi
56. Cosa Succede Se Abbiamo Più
Parametri?
•
Calcoliamo la frequenza di tutti i C colori in
un’immagine di P pixel
for (i=0; i<C; i++)
count[i] = 0;
for (i=0; i<P; i++)
count[value(i)]++;
sort(count);
•
•
•
56
// Initialize count
// Look at all pixels
// Increment count
// Sort pixel counts
Se usiamo C come parametri, allora T(n) = (C log C)
Se usiamo P come parametri, allora T(n) = (P)
È più accurato T(n) = (P + C log C)
Prof. Pier Luca Lanzi
57. Algoritmo di Ordinamento Merge Sort
•
Principio di base dell’algoritmo
Dato un vettore, suddividerlo in due sottovettori di uguale
lunghezza
Applicare il merge sort ai due sottovettori
Fondere i due sottovettori ―sfruttando‖ il fatto che sono ordinati
•
57
Pseudo codice
mergesort(array A)
if (|A|=1) return;
A1 ← mergesort(A[1..n/2]);
A2 ← mergesort(A[n/2+1 .. n]);
A ← merge(A1,A2);
Prof. Pier Luca Lanzi
58. Merge Sort in C++
http://www.ideone.com/9CZJu
// &A indica che il vettore A verra' modificato
void merge_sort(std::vector<int> &A)
{
std::vector<int> A1;
std::vector<int> A2;
if (A.size()==1) return;
for(int i=0; i<A.size()/2; i++)
A1.push_back(A[i]);
for(int i=A.size()/2; i<A.size(); i++)
A2.push_back(A[i]);
merge_sort(A1);
merge_sort(A2);
A = merge(A1,A2);
}
Prof. Pier Luca Lanzi
58
60. Merge Sort: Animazione da Wikipedia
Animazione del Merge Sort da Wikipedia
http://en.wikipedia.org/wiki/Merge_sort
http://upload.wikimedia.org/wikipedia/en/c/c5/Merge_sort_animation2.gif
Prof. Pier Luca Lanzi
60
62. Insertion Sort vs Merge Sort
•
•
•
•
•
62
InsertionSort
Ha un approccio incrementale
A[1..j-1] ordinato, aggiungi A[j]
MergeSort
Ha un approccio divide-et-impera
Tre passi: Divide, Impera, Combina
Divide: Divide il vettore di n elementi in due array
di n/2 elementi
Impera: Chiama il MergeSort ricorsivamente su i due
array
Combina: Fa il merge delle due sequenze ordinate
Prof. Pier Luca Lanzi
63. Analisi Asintotica del Merge Sort
T(n)
mergesort(array A)
c
if (|A|=1) return;
2T(n/2)
A1 ← mergesort(A[1..n/2]);
A2 ← mergesort(A[n/2+1 .. n]);
Θ(n)
A ← merge(A1,A2);
T(1) = Θ(1)
T(n) = 2T(n/2) + Θ(n)
Prof. Pier Luca Lanzi
63
64. Analisi Asintotica del Merge Sort
64
Calcolare T(n) = 2T(n/2) + cn, dove c > 0 è una constante
Prof. Pier Luca Lanzi
65. Analisi Asintotica del Merge Sort
65
Calcolare T(n) = 2T(n/2) + cn, dove c > 0 è una constante
T(n)
Prof. Pier Luca Lanzi
L1.65
66. Analisi Asintotica del Merge Sort
66
Calcolare T(n) = 2T(n/2) + cn, dove c > 0 è una constante
cn
T(n/2)
Prof. Pier Luca Lanzi
T(n/2)
67. Analisi Asintotica del Merge Sort
67
Calcolare T(n) = 2T(n/2) + cn, dove c > 0 è una constante
cn
cn/2
cn/2
T(n/4)
T(n/4)
Prof. Pier Luca Lanzi
T(n/4)
T(n/4)
68. Analisi Asintotica del Merge Sort
68
Calcolare T(n) = 2T(n/2) + cn, dove c > 0 è una costante
cn
cn/2
cn/2
cn/4
cn/4
Θ(1)
Prof. Pier Luca Lanzi
cn/4
cn/4
69. Analisi Asintotica del Merge Sort
69
Calcolare T(n) = 2T(n/2) + cn, dove c > 0 è una costante
cn
cn/2
cn/2
h = log n
cn/4
cn/4
Θ(1)
Prof. Pier Luca Lanzi
cn/4
cn/4
70. Analisi Asintotica del Merge Sort
70
Calcolare T(n) = 2T(n/2) + cn, dove c > 0 è una costante
cn
cn
cn/2
cn/2
h = log n
cn/4
cn/4
Θ(1)
Prof. Pier Luca Lanzi
cn/4
cn/4
71. Analisi Asintotica del Merge Sort
71
Calcolare T(n) = 2T(n/2) + cn, dove c > 0 è una costante
cn
cn
cn/2
cn/2
h = log n
cn/4
cn/4
Θ(1)
Prof. Pier Luca Lanzi
cn/4
cn
cn/4
72. Analisi Asintotica del Merge Sort
72
Calcolare T(n) = 2T(n/2) + cn, dove c > 0 è una costante
cn
cn
cn/2
cn/2
cn/4
cn/4
cn/4
cn/4
cn
…
h = log n
cn
Θ(1)
Prof. Pier Luca Lanzi
73. Analisi Asintotica del Merge Sort
73
Calcolare T(n) = 2T(n/2) + cn, dove c > 0 è una costante
cn
cn
cn/2
cn/2
cn/4
cn/4
cn/4
cn/4
cn
…
h = log n
cn
Θ(1)
n elementi
Prof. Pier Luca Lanzi
Q(n)
74. Analisi Asintotica del Merge Sort
74
Calcolare T(n) = 2T(n/2) + cn, dove c > 0 è una costante
cn
cn
cn/2
cn/2
cn/4
cn/4
cn/4
cn/4
cn
…
h = log n
cn
Θ(1)
n elementi
Q(n)
Total = Q(n log n)
Prof. Pier Luca Lanzi
75. Θ(nlogn) cresce più lentamente di Θ(n2)
Asintoticamente il merge sort è
meglio dell’insertion sort
In pratica il merge sort è
conveniente per n>30
Prof. Pier Luca Lanzi
76. Possiamo Parallelizzare il Merge Sort?
mergesort(array A)
if (|A|=1) return;
A1 ← mergesort(A[1..n/2]);
A2 ← mergesort(A[n/2+1 .. n]);
A ← merge(A1,A2);
Prof. Pier Luca Lanzi
76
77. Scalabilità nel Calcolo Parallelo?
Prof. Lanzi deve ordinare
N compiti
77
(Sequenziale)
Quanto ci mette
da solo?
(Caso Parallelo)
Quanto se ci sono 2
volontari?
(Caso Parallelo)
Quanto se ci sono
p volontari?
Prof. Pier Luca Lanzi
78. Counting Sort
•
•
78
I numeri da ordinare sono compresi in un range [1..k]
Costruire un array B[1..k] che conta il numero di volte che
compare un valore in [1..k]
Prof. Pier Luca Lanzi
79. Counting Sort in C++
http://www.ideone.com/muOp5
void counting_sort(std::vector<int> &A, unsigned int k)
{
// B e' un vettore di dimensione k inizializzato a 0
std::vector<int> B(k,0);
for(int i=0; i<A.size(); i++)
B[A[i]]++;
int j = 0;
for(int i=0; i<k; i++)
{
while (B[i]>0)
{
A[j] = i;
j++;
B[i]--;
}
}
}
Prof. Pier Luca Lanzi
79
80. Complessità del Counting Sort
•
•
•
•
•
80
La complessità del counting sort è O(n+k)
Se k è O(n), allora la complessità è O(n) quindi è il
migliore algoritmo visto finora
Però il Counting Sort non è basato su confronti e quindi si
applica solo a vettori di numeri interi
Abbiamo cambiato le condizioni di base
Inoltre, se k è O(n3), questo algoritmo è il peggiore
rispetto a tutti quelli visti finora
Prof. Pier Luca Lanzi
81. Qual è la Complessità dell’Ordinamento?
•
•
•
81
Abbiamo visto algoritmi di sort comparativi e il counting
sort
Per ordinare un insieme di elementi usa solo la
comparazione fra due elementi (insertion sort, merge sort,
quick sort)
La complessità migliore per il worst-case che abbiamo
visto finora è Θ(n lg n)
È Θ(n lg n) il meglio che possiamo fare?
Per rispondere usiamo gli alberi di decisione
Prof. Pier Luca Lanzi
82. Quanti Confronti?
•
•
82
Supponiamo di dover ordinare un vettore di tre elementi, a1, a2, e a3,
quanti/quali confronti dobbiamo effetuare?
Utilizziamo gli alberi di decisione, con questa notazione
i:j indica il confronto fra ai e aj
il sottoalbero sinistro rappresenta i confronti successivi se
ai ≤ aj quello destro i confronti se ai > aj
Ogni foglia contiene un possibile risultato
1:2
2:3
123
1:3
1:3
132
213
312
2:3
231
Prof. Pier Luca Lanzi
321
83. Esempio
•
83
Come esempio, proviamo ad ordinare il vettore <9,4,6>
a1 ≤ a2?
1:2
9
2:3
123
1:3
213
1:3
132
4
312
Prof. Pier Luca Lanzi
2:3
231
321
86. Alberi di Decisione come
Modello dell’Ordinamento
86
Un albero di decisione modella l’esecuzione di un
qualsiasi algoritmo di ordinamento per confronto
•
•
•
•
Ogni algoritmo basato su confronto può essere sempre descritto
tramite un albero di decisione
Cammino radice-foglia in un albero di decisione:
sequenza di confronti eseguiti dall'algoritmo corrispondente
Altezza dell'albero di decisione:
# confronti eseguiti dall'algoritmo corrispondente nel caso pessimo
Altezza media dell'albero di decisione:
# confronti eseguiti dall'algoritmo corrispondente nel caso medio
Prof. Pier Luca Lanzi
87. Limitazione Inferiore alla Complessità
dell’Ordinamento per Confronto
•
•
•
87
Lemma: Un albero di decisione per l'ordinamento di n elementi
contiene almeno n! Foglie
Lemma: Sia T un albero binario in cui ogni nodo interno ha
esattamente 2 figli e sia k il numero delle sue foglie. L'altezza
dell'albero è almeno log k
Teorema: Un albero di decisione per l’ordinamento di n elemento ha
altezza Ω(n lg n).
Dimostrazione: l’albero deve contenere almeno n! foglie quindi dato
che un albero di altezza h contiene al massimo 2h foglie si ha che
n!≤2h e quindi:
h ≥ lg(n!)
≥ lg ((n/e)n) (approssimazione Stirling)
= n lg n – n lg e
Prof. Pier Luca Lanzi
88. Limitazione Inferiore alla Complessità
dell’Ordinamento per Confronto
•
88
Corollario: Il merge sort è un algoritmo di ordinamento
basato su confronti asintoticamente ottimo.
Prof. Pier Luca Lanzi
89. Esercizi
•
•
89
Esercizio 1
Dato un array A[1..n] di interi e un intero v, scrivere un
programma C++ che determini se esistono due
elementi in A la cui somma è esattamente v
Esercizio 2
Siano date n monete d'oro, tutte dello stesso peso
tranne una contraffatta che pesa meno, ed una bilancia
con due piatti. Delineare un algoritmo per individuare la
moneta contraffatta in al più log n pesate.
Prof. Pier Luca Lanzi