Laboratorio di Algoritmi e Strutture Dati -...
Transcript of Laboratorio di Algoritmi e Strutture Dati -...
Argomenti del corso
Calcolo del tempo di computazione di un algoritmo:
I Esercizi di analisi formale: sommatorie, ricorrenze;
I Misurazione sperimentale dei tempi di calcolo;
Implementazione in C di alcuni algoritmi e strutture dati visti alezione:
I Algoritmi di Ricerca e Ordinamento;
I Strutture: liste concatenate, alberi, BST, RB-alberi, Grafi;
I Algoritmi ricorsivi e iterativi;
I Programmazione dinamica.
Variazioni di implementazioni usate frequentemente.
Lezioni frontali e (secondo disponibilita delle aule) in laboratorio.
Modalita d’esame
L’esame e in comune con il Prof. Massazza (15 CFU totali).
Per poter fare l’orale bisogna preparare un progetto in C:
I tre settimane a disposizione;
I si consegna indicativamente 7gg prima dell’orale (la data variaa seconda dell’appello);
I si discute nello stesso giorno dell’orale.
Tutte le informazioni sul sito del corso.
Materiale didattico
Materiale del corso (sul sito, a breve):
I file delle presentazioni;
I codice usato a lezione;
I calendario delle lezioni;
I avvisi di modifiche all’orario;
I avvisi per gli appelli;
I materiale aggiuntivo;
I links utili;
Per informazioni, contattatemi per posta elettronica.
e-mail: [email protected]
Testi di riferimento
Robert Sedgewick.Algoritmi in C.Addison-Wesley, Pearson Italia, 2002.
Brian W. Kernighan, Dennis M. Ritchie.Linguaggio C (seconda edizione),Nuova edizione italiana, Pearson, Italia, 2004.
Al Kelley, Ira Pohl.C Didattica e Programmazione (A book on C, 4th edition).Pearson, Italia, 2004.
Compilatore di riferimento
Useremo il compilatore gcc (GNU Compiler Collection).
Scaricatelo da
I per UNIX:
http://gcc.gnu.org/
I per Windows:
http://www.cs.colorado.edu/~main/cs1300/
Oppure un IDE qualunque
I es, DevCpp
Calcolo delle prestazioni degli algoritmi
Un algoritmo e un insieme di istruzioni finalizzate a risolvere unproblema.
I Ci possono essere piu algoritmi che risolvono lo stessoproblema.
I (ma un algoritmo risolve un solo problema).
Per valutare quale sia migliore si analizzano quante risorseimpegano per resituire una soluzione:
I tempo (di calcolo)
← soprattutto questo
I spazio (di memoria)
I banda (di rete)
I eccetera
Calcolo delle prestazioni degli algoritmi
Un algoritmo e un insieme di istruzioni finalizzate a risolvere unproblema.
I Ci possono essere piu algoritmi che risolvono lo stessoproblema.
I (ma un algoritmo risolve un solo problema).
Per valutare quale sia migliore si analizzano quante risorseimpegano per resituire una soluzione:
I tempo (di calcolo)
← soprattutto questo
I spazio (di memoria)
I banda (di rete)
I eccetera
Calcolo delle prestazioni degli algoritmi
Un algoritmo e un insieme di istruzioni finalizzate a risolvere unproblema.
I Ci possono essere piu algoritmi che risolvono lo stessoproblema.
I (ma un algoritmo risolve un solo problema).
Per valutare quale sia migliore si analizzano quante risorseimpegano per resituire una soluzione:
I tempo (di calcolo) ← soprattutto questo
I spazio (di memoria)
I banda (di rete)
I eccetera
Calcolo delle prestazioni degli algoritmi (cont.)
Il tempo di esecuzione dipende da molti fattori. Lo stessoalgoritmo impiega:
I tempo diverso su input diversi (1);
I tempi diversi sullo stesso input, quando e eseguito sucomputer diversi (2).
(1) Chiediamo che il tempo di esecuzione sia stimato in relazionealla grandezza dell’input.
(2) L’analisi di complessita degli algoritmi cerca di stabilire il tempodi calcolo indipendentemente dalla macchina sulla quale eimplementato il programma.
Calcolo delle prestazioni degli algoritmi (cont.)
Il tempo di esecuzione dipende da molti fattori. Lo stessoalgoritmo impiega:
I tempo diverso su input diversi (1);
I tempi diversi sullo stesso input, quando e eseguito sucomputer diversi (2).
(1) Chiediamo che il tempo di esecuzione sia stimato in relazionealla grandezza dell’input.
(2) L’analisi di complessita degli algoritmi cerca di stabilire il tempodi calcolo indipendentemente dalla macchina sulla quale eimplementato il programma.
Calcolo delle prestazioni degli algoritmi (cont.)
Il tempo di esecuzione dipende da molti fattori. Lo stessoalgoritmo impiega:
I tempo diverso su input diversi (1);
I tempi diversi sullo stesso input, quando e eseguito sucomputer diversi (2).
(1) Chiediamo che il tempo di esecuzione sia stimato in relazionealla grandezza dell’input.
(2) L’analisi di complessita degli algoritmi cerca di stabilire il tempodi calcolo indipendentemente dalla macchina sulla quale eimplementato il programma.
Esempio 1
Supponiamo che la stampa di un numero costi
1 secondo
e consideriamo un programma che legge un numero n e:
Caso A: stampa i numeri da 0 a n − 1.
Caso B: stampa tutte le coppie di numeri da 0 a n − 1.
Caso C: stampa tutte le potenze di 2 piu piccole di n.
Esempio 1 (cont.)Tabella di esecuzione
Al variare di n indichiamo quanti secondi spende ogni algoritmoper la stampa:
n A B C
1
1 1 1
2
2 4 2
3
3 9 2
4
4 16 3
5
5 25 3
10
10 100 4
20
20 400 5
50
50 2500 6
100
100 10000 71000 1.000 1.000.000 10106 106 1012 20
Esempio 1 (cont.)Tabella di esecuzione
Al variare di n indichiamo quanti secondi spende ogni algoritmoper la stampa:
n A B C
1 1
1 1
2 2
4 2
3 3
9 2
4 4
16 3
5 5
25 3
10 10
100 4
20 20
400 5
50 50
2500 6
100 100
10000 71000 1.000 1.000.000 10106 106 1012 20
Esempio 1 (cont.)Tabella di esecuzione
Al variare di n indichiamo quanti secondi spende ogni algoritmoper la stampa:
n A B C
1 1 1
1
2 2 4
2
3 3 9
2
4 4 16
3
5 5 25
3
10 10 100
4
20 20 400
5
50 50 2500
6
100 100 10000
71000 1.000 1.000.000 10106 106 1012 20
Esempio 1 (cont.)Tabella di esecuzione
Al variare di n indichiamo quanti secondi spende ogni algoritmoper la stampa:
n A B C
1 1 1 12 2 4 23 3 9 24 4 16 35 5 25 3
10 10 100 420 20 400 550 50 2500 6
100 100 10000 7
1000 1.000 1.000.000 10106 106 1012 20
Esempio 1 (cont.)Tabella di esecuzione
Al variare di n indichiamo quanti secondi spende ogni algoritmoper la stampa:
n A B C
1 1 1 12 2 4 23 3 9 24 4 16 35 5 25 3
10 10 100 420 20 400 550 50 2500 6
100 100 10000 71000
1.000 1.000.000 10106 106 1012 20
Esempio 1 (cont.)Tabella di esecuzione
Al variare di n indichiamo quanti secondi spende ogni algoritmoper la stampa:
n A B C
1 1 1 12 2 4 23 3 9 24 4 16 35 5 25 3
10 10 100 420 20 400 550 50 2500 6
100 100 10000 71000 1.000 1.000.000 10
106 106 1012 20
Esempio 1 (cont.)Tabella di esecuzione
Al variare di n indichiamo quanti secondi spende ogni algoritmoper la stampa:
n A B C
1 1 1 12 2 4 23 3 9 24 4 16 35 5 25 3
10 10 100 420 20 400 550 50 2500 6
100 100 10000 71000 1.000 1.000.000 10106
106 1012 20
Esempio 1 (cont.)Tabella di esecuzione
Al variare di n indichiamo quanti secondi spende ogni algoritmoper la stampa:
n A B C
1 1 1 12 2 4 23 3 9 24 4 16 35 5 25 3
10 10 100 420 20 400 550 50 2500 6
100 100 10000 71000 1.000 1.000.000 10106 106 1012 20
Esempio 1 (cont.)Le differenze tra il costo dei diversi algoritmi sono tanto piugrandi quanto e piu grande l’input.
Caso A se l’input raddoppia di grandezza, il costo raddoppia.
Caso B se l’input raddoppia di grandezza, il costo quadruplica.
Caso C se l’input raddoppia di grandezza, il costo aumenta di 1 sec.25
15
5
04 5321
n
10
20
Velocita di crescita delle funzioni
La complessita di un algoritmo deve quindi essere funzione delladimensione dell’input.
Per valori piccoli degli input, algoritmi con tempi di esecuzionediversi possono impiegare in realta tempi molto simili.
Ma quando gli input hanno dimensione maggiore, allora ladifferenza diventa rilevante.
Pseudo-codice
I Caso A:
for (i=0;i<n;i++)print(i);
I Caso B:
for (i=0;i<n;i++)for (j=0;j<n;j++)
print((i,j));
I Caso C:
for (i=1;i<n;i=2*i)print(i);
Esempio 1 (cont.)Tabella di esecuzione
Che succede se il costo passa da 1 a 50 secondi per operazione?
n A B C
1
50 50 50
2
100 200 100
3
150 450 100
4
200 800 150
5
250 1250 150
10
500 5000 200
50
2500 125000 300
100
5000 5000000 350
Esempio 1 (cont.)Tabella di esecuzione
Che succede se il costo passa da 1 a 50 secondi per operazione?
n A B C
1 50
50 50
2 100
200 100
3 150
450 100
4 200
800 150
5 250
1250 150
10 500
5000 200
50 2500
125000 300
100 5000
5000000 350
Esempio 1 (cont.)Tabella di esecuzione
Che succede se il costo passa da 1 a 50 secondi per operazione?
n A B C
1 50 50
50
2 100 200
100
3 150 450
100
4 200 800
150
5 250 1250
150
10 500 5000
200
50 2500 125000
300
100 5000 5000000
350
Esempio 1 (cont.)Tabella di esecuzione
Che succede se il costo passa da 1 a 50 secondi per operazione?
n A B C
1 50 50 502 100 200 1003 150 450 1004 200 800 1505 250 1250 150
10 500 5000 20050 2500 125000 300
100 5000 5000000 350
Esempio 1 (cont.)
Al crescere dell’input, i comportamenti restano uguali:
Caso A se l’input raddoppia di grandezza, il costo raddoppia.
Caso B se l’input raddoppia di grandezza, il costo quadruplica.
Caso C se l’input raddoppia, il costo aumenta di 50 sec.25
15
5
04 5321
n
10
20
0
n
2 54
1200
800
400
1 3
1000
600
200
Ecco perche...
L’analisi dei costi di un algoritmo:
1. si effettua in funzione della dimensione dell’input:I caso peggiore (su input di dimensione n)I caso ottimo (su input di dimensione n)I caso medio (su input di dimensione n)
I ma: su che distribuzione degli input?;
2. si studia spesso in termini di comportamento asintotico:I le costanti diventano importanti solo in situazioni particolari o
a parita di costo asintotico;I le equazioni che descrivono il costo diventano piu semplici.
Notazioni asintoticheRipasso delle definizioni
Def: siano f e g due funzioni da N in N.
I f (n) = O(g(n)) sse ∃c , n0 ∈ N | ∀n > n0, f (n) < cg(n);
I f (n) = Ω(g(n)) sse ∃c , n0 ∈ N | ∀n > n0, cf (n) > g(n);
I f (n) = Θ(g(n)) sse f (n) = O(g(n)) e f (n) = Ω(g(n)).
Esercizio 1: analisi di complessitaInsertion Sort
void insertionSort( int a[], int length ) int i, j, v;for ( i = 1; i < length; i++ ) j = i - 1;v = a[i];while ( ( j >= 0 ) && ( a[j] > v ) )
a[j+1] = a[j];j--;
a[j+1] = v;
I Caso migliore: Θ(n);
I Caso peggiore: Θ(n2);
I Caso medio: Θ(n2);
Esempio.
La funzione f : n ∈ N 7→ 2n e O(n).Infatti per n > 1 si ha 2n ≤ 3n.
Esercizi:
I 5n2 + n = O(n2) ?
I log2(8n) = O(n) ?
I n2 = O(n) ?
Alcune proprieta
O e Ω sono relazioni opposte.
I se g = O(f ) allora f = Ω(g)
Θ e una relazione di equivalenza!
Per ogni funz f g h da naturali a naturali
I f = Θ(f ) (riflessiva)
I se f = Θ(g) allora g = Θ(f ) (simmetrica)
I se f = Θ(g) e g = Θ(h) allora f = Θ(h) (transitiva)
In quanto tale, Θ divide le funzioni in classi di equivalenza.
Alcune proprieta
O e Ω sono relazioni opposte.
I se g = O(f ) allora f = Ω(g)
Θ e una relazione di equivalenza!
Per ogni funz f g h da naturali a naturali
I f = Θ(f ) (riflessiva)
I se f = Θ(g) allora g = Θ(f ) (simmetrica)
I se f = Θ(g) e g = Θ(h) allora f = Θ(h) (transitiva)
In quanto tale, Θ divide le funzioni in classi di equivalenza.
Alcune proprieta
O e Ω sono relazioni opposte.
I se g = O(f ) allora f = Ω(g)
Θ e una relazione di equivalenza!
Per ogni funz f g h da naturali a naturali
I f = Θ(f ) (riflessiva)
I se f = Θ(g) allora g = Θ(f ) (simmetrica)
I se f = Θ(g) e g = Θ(h) allora f = Θ(h) (transitiva)
In quanto tale, Θ divide le funzioni in classi di equivalenza.
Funzioni di riferimento
Si usano alcune funzioni di riferimento per la notazione asintotica.
I f = Θ(1) : f ha andamento costante
I f = Θ(log(N)) : f ha andamento logaritmico
I f = Θ(N) : f ha andamento lineare
I f = Θ(Nlog(N)) : f ha andamento pseudo-lineare
I f = Θ(N2) : f ha andamento quadratico
I f = Θ(N3) : f ha andamento cubico ...
I f = Θ(NK ) : f ha andamento polinomiale (K costante)
I f = Θ(KN) : f ha andamento esponenziale (K costante)
Sono classi di equivalenza per Θ! (una per ogni K ).
A parole
Per N abbastanza grandi, e a meno di una costantemoltiplicativia...f = O(g) significa “f vale meno di g”f = Ω(g) significa “f vale piu di g”f = Θ(g) significa “f e g si comportano allo stesso modo”
f = O(N2) significa “f ha andamento al piu quadratico”.f = Ω(N2) significa “f ha andamento almeno quadratico”.f = Θ(N2) significa “f ha andamento quadratico”.
Esercizio 2: AlberiQuanti nodi ha un albero k-ario completo di altezza h?
I il livello 0 contiene 1 nodo (la radice);
I il livello 1 contiene k nodi;
I il livello 2 contiene k2 nodi;
I il livello i contiene k i nodi;
1 + k + k2 + · · ·+ k(h−1) =h−1∑i=0
k i =kh − 1
k − 1
Esercizio 2: AlberiQuanti nodi ha un albero k-ario completo di altezza h?
I il livello 0 contiene 1 nodo (la radice);
I il livello 1 contiene k nodi;
I il livello 2 contiene k2 nodi;
I il livello i contiene k i nodi;
1 + k + k2 + · · ·+ k(h−1) =h−1∑i=0
k i =kh − 1
k − 1
Esercizio 2: AlberiQuanti nodi ha un albero k-ario completo di altezza h?
I il livello 0 contiene 1 nodo (la radice);
I il livello 1 contiene k nodi;
I il livello 2 contiene k2 nodi;
I il livello i contiene k i nodi;
1 + k + k2 + · · ·+ k(h−1) =h−1∑i=0
k i =kh − 1
k − 1
Esercizio 2: Alberi (cont.)
Quanti cammini diversi partono dalla radice?
I Esiste uno ed un solo cammino dalla radice ad ogni nodo:
kh − 1
k − 1− 1
E quant’e la lunghezza totale di questi cammini?
I (per i nodi a livello 1) ho k cammini di lunghezza 1;
I (per i nodi a livello 2) ho k2 cammini di lunghezza 2;
I (per i nodi a livello i) ho k i cammini di lunghezza i ;
k + 2k2 + · · ·+ (h − 1)kh−1 =h−1∑i=0
ik i
= k(h − 1)kh − hkh−1 + 1
(k − 1)2
Esercizio 2: Alberi (cont.)
Quanti cammini diversi partono dalla radice?
I Esiste uno ed un solo cammino dalla radice ad ogni nodo:
kh − 1
k − 1− 1
E quant’e la lunghezza totale di questi cammini?
I (per i nodi a livello 1) ho k cammini di lunghezza 1;
I (per i nodi a livello 2) ho k2 cammini di lunghezza 2;
I (per i nodi a livello i) ho k i cammini di lunghezza i ;
k + 2k2 + · · ·+ (h − 1)kh−1 =h−1∑i=0
ik i = k(h − 1)kh − hkh−1 + 1
(k − 1)2
Esercizio 2: Alberi (cont.)
Quanti cammini diversi partono dalla radice?
I Esiste uno ed un solo cammino dalla radice ad ogni nodo:
kh − 1
k − 1− 1
E quant’e la lunghezza totale di questi cammini?
I (per i nodi a livello 1) ho k cammini di lunghezza 1;
I (per i nodi a livello 2) ho k2 cammini di lunghezza 2;
I (per i nodi a livello i) ho k i cammini di lunghezza i ;
k + 2k2 + · · ·+ (h − 1)kh−1 =h−1∑i=0
ik i = k(h − 1)kh − hkh−1 + 1
(k − 1)2
Esercizio 2: Alberi (cont.)
Quanti cammini diversi partono dalla radice?
I Esiste uno ed un solo cammino dalla radice ad ogni nodo:
kh − 1
k − 1− 1
E quant’e la lunghezza totale di questi cammini?
I (per i nodi a livello 1) ho k cammini di lunghezza 1;
I (per i nodi a livello 2) ho k2 cammini di lunghezza 2;
I (per i nodi a livello i) ho k i cammini di lunghezza i ;
k + 2k2 + · · ·+ (h − 1)kh−1 =h−1∑i=0
ik i = k(h − 1)kh − hkh−1 + 1
(k − 1)2
Tipico problemino
Problema della ricerca su vettore ordinato.“Dato un vettore ordinato a di valori e un valore v , capire se v epresente in a e, se se lo e, a quale posizione.”Vediamo due possibili algoritmi per questo problema.Algoritmo 1: Ricerca lineare (o esaustiva)Algoritmo 2: Ricerca binaria
Ricerca lineare
Implementazione:
int linearSearch( int a[], int length, int v ) int i;for (i=0; i<length; i++) if ( a[i] == v) return i; /* trovato! */
return -1; /* non l’ho trovato */
Complessita? Caso ottimo?
Caso pessimo?E il caso medio?
Ricerca binaria
int binarySearch( int a[], int length, int v ) int m, r = length - 1, l = 0;while( r >= l ) m = ( l + r ) / 2;if ( v == a[m] ) return m;if ( v < a[m] ) r = m - 1;
else l = m + 1;return -1;
Complessita? Ogni test esclude meta dell’array:
T (n) ≤ T (bn/2c) + 1 (considero solo i confronti).
T (n) ≤ log2 n + 1
E il caso medio?