La presentazione è in caricamento. Aspetta per favore

La presentazione è in caricamento. Aspetta per favore

17.11.20031 Analisi di un algoritmo F. Bombi 17 novembre 2003.

Presentazioni simili


Presentazione sul tema: "17.11.20031 Analisi di un algoritmo F. Bombi 17 novembre 2003."— Transcript della presentazione:

1 Analisi di un algoritmo F. Bombi 17 novembre 2003

2 Analisi delle risorse Per valutare la qualità di un algoritmo siamo interessati a valutare le risorse di cui ha bisogno un programma che lo realizzi Consideriamo i componenti principali di un calcolatore – Unità centrale di elaborazione (CPU) – Memoria centrale – Dispositivi di memoria di massa Nella nostra trattazione elementare abbiamo studiato solo algoritmi che operano con i dati in memoria per cui analizzeremo solo lutilizzo della CPU e della memoria centrale

3 Utilizzo della memoria Nel nostro modello semplificato di calcolatore possiamo pensare che la memoria centrale sia divisa in tre aree distinte o segmenti – Il segmento statico utilizzato per contenere il codice del programma e le costanti – Il segmento dinamico (free store o heap) utilizzato per contenere gli oggetti creati dinamicamente e soggetto a garbage collection – Lo stack (run time stack) utilizzato per lallocazione delle variabili locali create allinterno di un blocco al momento della sua attivazione

4 Il segmento statico Gli algoritmi elementari, oggetto del nostro corso, portano a programmi di modeste dimensioni per cui lutilizzo di memoria per la parte statica può essere trascurato Non dobbiamo comunque dimenticare che è possibile aumentare la velocità di un programma trasformando un ciclo in una sequenza di istruzioni senza confronti e salti. In questo modo si risparmia sulla risorsa tempo a spese dellimpiego di memoria statica

5 Memoria dinamica Lingombro della memoria dinamica è invece un parametro che ci può aiutare a scegliere fra soluzioni diverse di un problema In certi casi infatti è possibile individuare soluzioni che richiedono un tempo minore a spese di un maggior utilizzo della memoria. Ad esempio: – mergesort richiede uno spazio di memoria doppio, rispetto agli algoritmi elementari, per contenere una copia del vettore da ordinare – un dizionario in una tabella, quando le chiavi sono sparse, richiede di utilizzare molto più spazio di una rappresentazione con una lista

6 Utilizzo del run time stack Lo stack durante lesecuzione di un programma contiene le variabili dichiarate allinterno del blocco che costituisce il corpo di ogni metodo Le variabili vengono allocate al momento dellattivazione del blocco e rilasciate quando si esce dal blocco per cui occupano spazio solo durante le chiamate al metodo Lutilizzo dello stack può essere un fattore critico nei metodi ricorsivi in quanto un nuovo blocco viene creato ad ogni attivazione ricorsiva di un metodo senza rilasciare il blocco precedente Le dimensioni dello stack sono quindi proporzionali alla profondità di ricorsione che rappresenta di conseguenza un parametro importante per valutare la qualità della soluzione adottata

7 Utilizzo della CPU: il tempo Nel nostro modello lunità centrale di elaborazione esegue ciclicamente una istruzione alla volta, di conseguenza il tempo necessario alla soluzione di un dato problema è proporzionale al numero di cicli (inversamente proporzionale alla frequenza di clock del processore utilizzato e proporzionale al numero di istruzione eseguite) Il tempo necessario a risolvere un dato problema rappresenta spesso il parametro più importante nella valutazione della qualità di un algoritmo Infatti mentre possiamo immaginare di aumentare le dimensioni della memoria di una macchina a piacere, il tempo non è un bene replicabile Vedremo come anche aumentando la frequenza di clock algoritmi inefficienti non consentono di risolvere problemi di grandi dimensioni

8 Il tempo Per valutare il tempo necessario alla soluzione di un dato problema sarebbe necessario stimare il numero di istruzioni in funzione delle dimensioni o taglia del problema La stima è impossibile quando si utilizzi un linguaggio ad alto livello in quanto il numero di istruzioni macchina corrispondente ad una istruzione nel linguaggio ad alto livello dipende dal compilatore impiegato È comunque significativo stimare quale sia il comportamento asintotico del numero di istruzioni necessario alla soluzione del problema in funzione della taglia, a meno di una costante Tale stima viene comunemente indicato come complessità temporale dellalgoritmo impiegato

9 Comportamento asintotico taglia n n Le funzioni che legano il numero di istruzioni necessarie alla soluzione di un problema alla sua taglia n non sono, come vedremo con qualche esempio, in genere continue e non ammettono un limite per n tendente allinfinito Per descrivere il comportamento asintotico ci dobbiamo accontentare di una stima del limite superiore utilizzando la notazione O-grande O(g(n)) Indichiamo con O(g(n)) un insieme di funzioni I = {f(n), f(n), …} cn 0 per ognuna delle quali esistono due costanti positive c e n 0 tali per cui 0 f(n) cg(n) per ogni n n 0 per indicare che una funzione appartiene allinsieme si dice f(n) è O(g(n))

10 n f(n) n cn n0n0n0n0 f(n)= O(n)

11 Attenzione O(n)O(n 2 ) O(n 3 ) Fare attenzione che dalle definizioni date una funzione che è O(n) è anche O(n 2 ) oppure O(n 3 ) In genere nel valutare il comportamento asintotico si cercherà di trovare la funzione che cresce più lentamente e che quindi limita in modo più stretto il comportamento asintotico

12 Esempio: ricerca in un vettore Rivediamo, come ripasso, lanalisi dellalgoritmo di ricerca di un elemento in un vettore, il metodo restituisce la posizione dellelemento cercato se presente, -1 se non presente int scansione (Comparable x, Comparable[] v, int n) { for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) if (x.compareTo(v[i]) == 0) if (x.compareTo(v[i]) == 0) return i; return i; return -1; return -1; } Per chiarezza conviene per prima cosa riscrivere il programma trasformando il ciclo for in un ciclo while equivalente

13 int scansione (Comparable x, Comparable[] v, int n) int scansione (Comparable x, Comparable[] v, int n) { int i = 0; { int i = 0; while (i < n) while (i < n) { if (x.compareTo(v[i]) == 0) { if (x.compareTo(v[i]) == 0) return i; return i; i++; i++; } return -1; return -1; } Se supponiamo ora di conoscere il tempo necessario per eseguire ciascuna istruzione siamo in grado di valutare il tempo necessario a risolvere il problema determinando quante volte ciascuna istruzione verrà eseguita in funzione dei dati in ingresso. k i Indichiamo con k i il tempo necessario allesecuzione di ciascuna essere sicuri che le costanti istruzione, lunica cosa importante è essere sicuri che le costanti non dipendano dalla taglie del problema non dipendano dalla taglie del problema che nel nostro caso è la n lunghezza n del vettore su cui si deve effettuare la ricerca

14 k 1 int i = 0; k 2 while (i < n) k 3 { if (x.compareTo(v[i]) == 0) k 4 return i; k 5 i++; } k 6 return -1; 1 int i = 0; c+1-s while (i < n) c { if (x.compareTo(v[i]) == 0) s return i; c-s i++; } 1-s return -1; s = 1 successo c = posizione s = 0 insuccesso c = n i = 0 while (i < n) if (x.compareTo(v[i]) == 0) return i i++ return -1 Il tempo complessivo necessario a ritrovare lelemento cercato è dato da: t=f(n)=k 1 +(c+1-s)k 2 + ck 3 + sk 4 + (c-s)k 5 + (1-s)k 6

15 Il tempo complessivo necessario a ritrovare lelemento cercato è dato da: t=f(n)= k 1 + (c+1-s)k 2 + ck 3 + sk 4 + (c-s)k 5 + (1-s)k 6 e quindi: t=f(n)= k 1 +k 2 +k 6 + s(k 4 -k 2 -k 5 -k 6 ) + c(k 2 +k 3 +k 5 ) = a 1 + a 2 s + a 3 c Se lelemento cercato non è presente: s = 0, c = n t = a 1 + a 3 n Se lelemento cercato è presente al posto c: s = 1 Caso migliore (c = 1) t = a 1 + a 2 + a 3 Caso peggiore (c = n) t = a 1 + a 2 + a 3 n Caso medio (tutte le posizioni sono equiprobabili) t = a 1 + a 2 + a 3 (n+1)/2

16 Conclusioni ka processore Le costanti k o a delle espressioni appena viste dipendono dal compilatore impiegato e dal processore inversamente proporzionali al clock In particolare sappiamo che sono (in prima approssimazione) inversamente proporzionali al clock della macchina impiegata O(n) O(1) Indipendentemente da questi parametri possiamo però dire che la ricerca richiede un tempo che è O(n) in caso di insuccesso e, in caso di successo, in media o nel caso peggiore. Il tempo richiesto è invece O(1) nel caso migliore

17 Il paradosso del comportamento asintotico È ragionevole domandare perché siamo tanto preoccupati dal tempo impiegato da un algoritmo per risolvere un dato problema Sappiamo che ogni 18 mesi i microelettronici sfornano un nuovo processore che ha circa il doppio della potenza di calcolo del precedente, se un problema non è risolvibile con la tecnologia di oggi sarà risolvibile domani? Questo è vero solo se disponiamo di un algoritmo efficiente per la soluzione del problema e ce ne possiamo rendere conto osservando la seguente tabella

18 Tempo in funzione di n log n 0123 n n n n log n n2n2n2n e6 n3n3n3n e61e9 2n2n2n2n21e31e301e300

19 Dimensioni massime del problema risolvibile 0.1f(n) Nella prossima tabella consideriamo le dimensioni di un problema risolvibile in 1 secondo, 1 minuto, 1 ora o 1 giorno supponendo di utilizzare algoritmi che richiedono un tempo pari a 0.1f(n) secondi Possiamo notare che il passaggio dalla prima alla seconda colonna corrisponde allutilizzo di un tempo 60 volte maggiore oppure, a parità di tempo, di un processore 60 volte maggiore (circa 9 anni di progresso tecnologico)

20 Dimensioni in funzione del tempo 10 f(n) 1 sec 1 minuto 1 ora 1 giorno log n 1006e31e360001e n n1003.6e51.3e97.5e11 n e48.6e5 n log n e31.65e5 n2n2n2n n3n3n3n n2n2n2n391520


Scaricare ppt "17.11.20031 Analisi di un algoritmo F. Bombi 17 novembre 2003."

Presentazioni simili


Annunci Google