La presentazione è in caricamento. Aspetta per favore

La presentazione è in caricamento. Aspetta per favore

Didattica dei Fondamenti dellInformatica 2 Seconda giornata: progettare un algoritmo corretto, efficiente, e possibilmente ottimo! Guido Proietti Email:

Presentazioni simili


Presentazione sul tema: "Didattica dei Fondamenti dellInformatica 2 Seconda giornata: progettare un algoritmo corretto, efficiente, e possibilmente ottimo! Guido Proietti Email:"— Transcript della presentazione:

1 Didattica dei Fondamenti dellInformatica 2 Seconda giornata: progettare un algoritmo corretto, efficiente, e possibilmente ottimo! Guido Proietti URL: 1

2 Richiamo: Complessità computazionale di un algoritmo e di un problema Definizione Un algoritmo A ha una complessità computazionale O(f(n)) su istanze di dimensione n se T(n)=O(f(n)), ove T(n) è il numero di passi elementari dellalgoritmo sulle istanze di ingresso di dimensione n che comportano più lavoro per lalgoritmo stesso (ovvero, T(n) misura il caso peggiore dellalgoritmo) Definizione Un problema P ha una complessità computazionale O(f(n)) se esiste un algoritmo che risolve P la cui complessità computazionale è O(f(n)) 2

3 Richiamo: gerarchia delle classi Decidibili ExpTime (ARRESTO(k)) P (ricerca) NP NP-completi (SAT) 3

4 Progettare un algoritmo Vogliamo progettare algoritmi (per problemi calcolabili!) che: –Producano correttamente il risultato desiderato –Siano efficienti in termini di tempo di esecuzione ed occupazione di memoria 4

5 Le quattro proprietà fondamentali di un algoritmo (oltre lefficienza) La sequenza di istruzioni deve essere finita Essa deve portare ad un risultato corretto Le istruzioni devono essere eseguibili materialmente Le istruzioni non devono essere ambigue 5

6 Algoritmi e strutture dati Concetto di algoritmo è inscindibile da quello di dato Da un punto di vista computazionale, un algoritmo è una procedura che prende dei dati in input e, dopo averli elaborati, restituisce dei dati in output I dati devo essere organizzati e strutturati in modo tale che la procedura che li elabora sia efficiente 6

7 Analisi di algoritmi Correttezza: –dimostrare formalmente che un algoritmo è corretto Complessità: –Stimare la quantità di risorse (tempo e memoria) necessarie allalgoritmo –stimare il più grande input gestibile in tempi ragionevoli –confrontare due algoritmi diversi –ottimizzare le parti critiche 7

8 f(n) = (g(n)) se due costanti c>0 e n 0 0 tali che f(n) c g(n) per ogni n n 0 Notazione asintotica n0n0 n f(n) = ( g(n) ) f(n) c g(n) 8

9 Esempi Sia f(n) = 2n 2 - 5n; vogliamo dimostrare che f(n)= (n 2 ). f(n)/n 2 = (2n 2 - 5n)/n 2 = 2 - 5/n ma 2 - 5/n 1 per n 5 quindi basta scegliere c=1 e n 0 =5 e avremo che 2n 2 - 5n 1n 2 per n n 0 =5. f(n) = (n) (c=1, n 0 =2) f(n) = (log n) (c=1, n 0 =2) Invece, f(n) (n 3 ) 9

10 Legame con il concetto di limite 10

11 f(n) = (g(n)) se tre costanti c 1,c 2 >0 e n 0 0 tali che c 1 g(n) f(n) c 2 g(n) per ogni n n 0 Notazione asintotica n0n0 n f(n) = ( g(n) ) f(n) c 1 g(n) c 2 g(n) 11

12 Relazioni tra O, e Θ 12

13 Sia tempo(I) il tempo di esecuzione di un algoritmo sullistanza I T best (n) = min istanze I di dimensione n {tempo(I)} Intuitivamente, T best (n) è il tempo di esecuzione sulle istanze di ingresso che comportano meno lavoro per lalgoritmo Caso migliore di un algoritmo 13

14 Sia P (I) la probabilità di occorrenza del- listanza I T avg (n) = istanze I di dimensione n { P (I) tempo(I) } Intuitivamente, T avg (n) è il tempo di esecuzione nel caso medio, ovvero sulle istanze di ingresso tipiche per il problema Richiede di conoscere una distribuzione di probabilità sulle istanze Caso medio di un algoritmo 14

15 Dato un insieme S di n elementi presi da un dominio totalmente ordinato, ordinare S IL problema: lordinamento Esempi: ordinare una lista di nomi alfabeticamente, o un insieme di numeri, o un insieme di compiti desame in base al cognome dello studente Subroutine in molti problemi È possibile effettuare ricerche in array ordinati in tempo O(log n) (ricerca binaria) 15

16 Il problema dellordinamento (non decrescente) Input: una sequenza di n numeri (reali) (NOTA: la dimensione dellinput è n) Output: una permutazione {1,2,…,n} {i 1,i 2,…,i n }, ovvero un riarrangiamento della sequenza di input in modo tale che a i 1 a i 2 … a i n 16

17 SelectionSort Approccio incrementale: assumendo che i primi k elementi siano ordinati, estende lordinamento ai primi k+1 elementi scegliendo il minimo degli n-k elementi non ancora ordinati e mettendolo in posizione k+1 17

18 SelectionSort (A) 1. for k=1 to n-1 do 2. m = k 3. for j=k+1 to n do 4. if (A[j] < A[m]) then m=j 5. scambia A[m] con A[k] linea 2: m mantiene lindice dellarray in cui si trova il minimo corrente linee 3-4: ricerca del minimo fra gli elementi A[k],…,A[n] (m viene aggiornato con lindice dellarray in cui si trova il minimo corrente) linea 5: il minimo è spostato in posizione k NOTA: Assumiamo che il primo elemento dellarray sia in A[1] 18

19 Correttezza Si dimostra facendo vedere che alla fine del generico passo k (k=1,…, n-1) si ha: (i) i primi k elementi sono ordinati e (ii) contengono i k elementi più piccoli dellarray Induzione su k: –k=1: Alla prima iterazione viene semplicemente selezionato lelemento minimo dellarray (i) e (ii) banalmente verificate. –k>1. Allinizio del passo k i primi k-1 elementi sono ordinati e sono i k-1 elementi più piccoli nellarray (ipotesi induttiva). Allora la tesi segue dal fatto che lalgoritmo seleziona il minimo dai restanti n-k elementi e lo mette in posizione k. Infatti: (ii) i primi k elementi restano i minimi nellarray (i) lelemento in posizione k non è mai più piccolo dei primi k-1 elementi 19

20 Complessità temporale SelectionSort (A) 1. for k=1 to n-1 do 2. m = k 3. for j=k+1 to n do 4. if (A[j] < A[m]) then m=j 5. scambia A[m] con A[k] n-k confronti (operaz. dominante) 1 scambio (3 assegnamenti) il tutto eseguito per k=1,…, n-1 T(n) = [1+(n-k)+1]=2(n-1)+ k =2(n-1)+n·(n-1)/2 = (n 2 ) k=1 n-1 T(n) = T best (n) = T avg (n) = (n 2 ) k=1 n-1 1 assegnamento Si noti che T(n) è PROPRIO UGUALE ad un polinomio di 2º grado in n, e quindi la notazione Θ è perfettamente ESPRESSIVA del valore di T(n) 20

21 InsertionSort Approccio incrementale: assumendo che i primi k elementi siano ordinati, estende lordinamento ai primi k+1 elementi, inserendo lelemento in posizione k+1-esima nella giusta posizione rispetto ai primi k elementi 21

22 InsertionSort (A) 1. for k=1 to n-1 do 2. x = A[k+1] 3. for j=1 to k+1 do 4. if (A[j] > x) then break 5. if (j < k+1) then 6. for t=k downto j do A[t+1]= A[t] 7. A[j]=x Linea 2: elemento x=A[k+1] da inserire nella posizione che gli compete Linee 3 e 4: individuano la posizione j in cui va messo x Linee 5 e 6: se la posizione j è diversa da k+1, si fa spazio per inserire x, shiftando tutti gli elementi da j a k verso destra 22

23 Correttezza Si dimostra facendo vedere che alla fine del generico passo k (k=1,…, n-1) i primi k+1 elementi sono ordinati (si noti la differenza con il Selection Sort, in cui invece dovevamo far vedere anche che erano i più piccoli) Induzione su k: –k=1: banale: si riordinano A[1] e A[2]; –k>1: Allinizio del passo k i primi k elementi sono ordinati (ipotesi induttiva). Allora la tesi segue dal fatto che lalgoritmo inserisce A[k+1] nella giusta posizione rispetto alla sequenza A[1],…,A[k] 23

24 InsertionSort (A) 1. for k=1 to n-1 do 2. x = A[k+1] 3. for j=1 to k+1 do 4. if (A[j] > x) then break 5. if (j < k+1) then 6. for t=k downto j do A[t+1]= A[t] 7. A[j]=x T(n) = (n)+ (k+1) = (n 2 ) j*k+1 confronti k+1–j* assegnamenti il tutto eseguito per k=1,…, n-1 k=1 n-1 T(n) = T best (n) = T avg (n) = (n 2 ) Possiamo fare meglio? k+1 oper. Complessità temporale 24 1 assegnamento

25 InsertionSort2 (A) 1. for k=1 to n-1 do 2. x = A[k+1] 3. j = k 4. while j > 0 e A[j] > x do 5. A[j+1] = A[j] 6. j= j-1 7. A[j+1]=x il tutto eseguito per k=1,…, n-1 t k 2k assegnam. tempo(n)= (n)+ t k (n)+ 2k = (n)+n·(n-1) = (n 2 ) tempo(n) = O(n 2 ) k=1 n-1 k=1 n-1 Una variante dellIS più efficiente Si noti che tempo(n) è AL PIÙ UGUALE ad un polinomio di 2º grado in n, e quindi la notazione O è perfettamente ESPRESSIVA del valore di T(n) 25

26 Caso migliore, peggiore, e medio di InsertionSort2 Caso migliore –array già ordinato in ordine crescente t k = 0 T best (n) = (n) (costo del ciclo for esterno) Caso peggiore –array ordinato in ordine decrescente t k = 2k T(n) = 2k = (n 2 ) Caso medio –Lelemento in posizione k+1 ha la medesima probabilità di essere inserito in ciascuna delle k posizioni che lo precedono la sua posizione attesa è k/2 il valore atteso di t k = k T avg (n) = k = (n 2 ) k=1 n-1 26

27 Legge di Murphy? « Se qualcosa può andar male, lo farà. » In realtà, negli algoritmi il caso medio costa spesso come il caso peggiore (asintoticamente), in quanto le strutture di controllo fondamentali degli algoritmi sono i cicli, e spesso il caso medio implica lesecuzione della metà delle istruzioni di un ciclo, senza quindi avere un abbattimento asintotico della complessità. 27

28 Riepilogo Insertion Sort 2 Insertion Sort 1 Θ(n) Caso migliore Selection Sort Θ(n 2 ) Caso medio Θ(n 2 ) Caso peggiore 28

29 Complessità spaziale Ricordiamo che oltre alla complessità temporale dobbiamo valutare anche la complessità spaziale di un algoritmo, ovvero lo spazio di memoria necessario per ospitare le strutture di dati utilizzate dallalgoritmo. La complessità spaziale del Selection Sort e dellInsertion Sort è Θ (n) Nota: Se la complessità spaziale di un certo algoritmo è Θ(g(n)), e se tale algoritmo ispeziona lintera memoria occupata, allora la complessità temporale dellalgoritmo è (g(n)), ovviamente. 29

30 Conseguenze per il problema dellordinamento La complessità spaziale di qualsiasi algoritmo che risolve il problema dellordinamento è (n) (dimensione input) …ma qualsiasi algoritmo che risolve il problema dellordinamento deve ispezionare tutti i dati in ingresso, e quindi ha complessità temporale T(n)= (n) Tutti gli algoritmi che risolveranno il problema dellordinamento avranno una complessità temporale (n) 30

31 Delimitazioni inferiori (lower bound) Definizione Un algoritmo A ha complessità computazionale (g(n)) su istanze di dimensione n se T(n)= (g(n)) (significa che numero di passi elementari necessari per eseguire A nel caso peggiore è (g(n)), e quindi non è detto che debbano essere necessari per ogni istanza di dimensione n: istanze facili potrebbero richiedere meno risorse!) Definizione (lower bound o complessità intrinseca di un problema) Un problema P ha una delimitazione inferiore alla complessità computazionale (g(n)) se ogni algoritmo che risolve P ha complessità computazionale (g(n)). 31

32 Ottimalità di un algoritmo Definizione Dato un problema P con complessità intrinseca (g(n)), un algoritmo che risolve P è ottimo (in termini di complessità asintotica, ovvero a meno di costanti moltiplicative e di termini additivi/sottrattivi di magnitudine inferiore) se ha complessità computazionale O(g(n)). 32

33 Quindi, per il problema dellordinamento… Upper bound temporale: O(n 2 ) –Insertion Sort, Selection Sort Lower bound temporale: (n) –banale: dimensione dellinput Abbiamo un gap lineare tra upper bound e lower bound! Possiamo fare meglio, ovvero abbassare lupper bound e/o innalzare il lower bound ? 33

34 Ordinamento per confronti Dati due elementi a i ed a j, per determinarne lordinamento relativo effettuiamo una delle seguenti operazioni di confronto: a i a j ; a i a j ; a i a j ; a i a j ; a i a j Non si possono esaminare i valori degli elementi o ottenere informazioni sul loro ordine in altro modo. Notare: Tutti gli algoritmi di ordinamento considerati fino ad ora sono algoritmi di ordinamento per confronto. 34

35 Consideriamo un generico algoritmo A, che ordina eseguendo solo confronti: dimostreremo che A esegue (nel caso peggiore) (n log n) confronti Un generico algoritmo di ordinamento per confronti lavora nel modo seguente: -Confronta due elementi a i ed a j (ad esempio effettua il test a i a j ); -A seconda del risultato, riordina e/o decide il confronto successivo da eseguire. Un algoritmo di ordinamento per confronti può essere descritto in modo astratto usando un albero di decisione, nel quale i nodi interni rappresentano i confronti, mentre le foglie rappresentano gli output prodotti Lower bound (n log n) per lordinamento 35

36 Descrive le diverse sequenze di confronti che A esegue su unistanza di lunghezza n; i movimenti dei dati e tutti gli altri aspetti dellalgoritmo vengono ignorati Nodo interno (non foglia): i:j (modella il confronto tra a i e a j ) Nodo foglia: i 1,i 2,…,i n (modella una risposta (output) dellalgoritmo, ovvero una permutazione degli elementi) Lalbero di decisione è associato ad un algoritmo e alla dimensione n dellistanza Albero di decisione 36

37 Esempio Input Riconoscete lalgoritmo associato? È proprio lInsertion Sort 2! Esercizio per casa: costruire lalbero di decisione per il SS su una sequenza di 3 elementi. 37

38 Per una particolare istanza, i confronti eseguiti da A su quella istanza rappresentano un cammino radice – foglia Lalgoritmo segue un cammino diverso a seconda delle caratteristiche dellinput –Caso peggiore: cammino più lungo –Caso migliore: cammino più breve Il numero di confronti nel caso peggiore è pari allaltezza dellalbero di decisione (ovvero alla lunghezza, in termini di numero di archi, del più lungo cammino radice-foglia) Proprietà 38

39 Lemma: Un albero strettamente binario (ovvero, in cui ogni nodo interno ha esattamente due figli) con k foglie ha altezza h(k) log 2 k. Dim: Dimostrazione per induzione su k: –Caso base k=1 (albero-nodo ): banale h(k)=0 log 2 1=0 –Caso k>1: supposto vero per k-1 foglie, dimostriamolo per k; poiché la radice ha 2 figli, uno dei due suoi sottoalberi deve contenere almeno la metà (parte intera sup.) delle foglie, e quindi h(k) 1+h( k/2 ) (hp induttiva) 1+log 2 (k/2) =1+log 2 k-log 2 2=log 2 k. QED Altezza in funzione delle foglie 39

40 Consideriamo lalbero di decisione di un qualsiasi algoritmo che risolve il problema dellordinamento di n elementi Tale albero deve avere almeno n! foglie: infatti, se lalgoritmo è corretto, deve contemplare tutti i possibili output, ovvero le n! permutazioni della sequenza di n elementi in input Dal lemma precedente, avremo che laltezza h(n) dellalbero di decisione sarà: Il lower bound (n log n) h(n) log 2 (#foglie) log 2 (n!) Formula di Stirling: n! (2 n) 1/2 ·(n/e) n > (n/e) n > log 2 (n/e) n = = n log 2 (n/e) = n log 2 n – n log 2 e = = (n log n) QED = 40

41 Problema dellordinamento: –Lower bound - (n log n) albero di decisione –Upper bound – O(n 2 ) IS,SS Proviamo a costruire un algoritmo ottimo, usando la tecnica del divide et impera: 1 Divide: dividi larray a metà 2 Risolvi il sottoproblema ricorsivamente 3 Impera: fondi le due sottosequenze ordinate Un algoritmo ottimo: il MergeSort (John von Neumann, 1945) 41

42 Esempio di esecuzione Input ed output delle chiamate ricorsive 42

43 Due array ordinati A e B possono essere fusi rapidamente: –estrai ripetutamente il minimo di A e B e copialo nellarray di output, finché A oppure B non diventa vuoto –copia gli elementi dellarray non ancora completamente svuotato alla fine dellarray di output Fusione di sequenze ordinate Notazione: dato un array A e due indici x y, denotiamo con A[x;y] la porzione di A costituita da A[x], A[x+1],…,A[y] 43

44 Merge (A, i 1, f 1, f 2 ) 1. Sia X un array ausiliario di lunghezza f 2 -i i=1 3. i 2 =f while (i 1 f 1 e i 2 f 2 ) do 5. if (A[i 1 ] A[i 2 ]) 6. then X[i]=A[i 1 ] 7. incrementa i e i 1 8. else X[i]=A[i 2 ] 9. incrementa i e i if (i 1

45 Lemma La procedure Merge fonde due sequenze ordinate di lunghezza n 1 e n 2 eseguendo al più n 1 + n 2 -1 confronti Dim: Ogni confronto consuma un elemento di A. Nel caso peggiore tutti gli elementi tranne lultimo sono aggiunti alla sequenza X tramite un confronto. Il numero totale di elementi è n 1 + n 2. Quindi il numero totale di confronti è n 1 + n QED Numero di confronti: C(n=n 1 + n 2 )=O(n 1 + n 2 )=O(n) (si noti che vale anche C(n)=Ω(min{n 1,n 2 })) Numero di operazioni (confronti + copie)? T(n)= (n 1 + n 2 ) Costo dellalgoritmo di merge 45

46 MergeSort (A, i, f) 1. if (i f) then return 2. m = (i+f)/2 3. MergeSort(A,i,m) 4. MergeSort(A,m+1,f) 5. Merge(A,i,m,f) MergeSort 46

47 Complessità del MergeSort Si vede facilmente che il tempo di esecuzione di MergeSort è: T(n) = 2 T(n/2) + Θ(n) con T(1)=1, da cui: T(n)=2(2T(n/2 2 )+Θ(n/2))+Θ(n)= =2(2(2T(n/2 3 )+Θ(n/2 2 ))+Θ(n/2))+Θ(n)=… e per k = log 2 n si ha n/2 k = 1 e quindi T(n)=2(2(…(2T( n/2 k )+Θ(1))+…+Θ(n/2 2 ))+Θ(n/2))+Θ(n) = 2 log n ·Θ(1)+2 log n -1 ·Θ(2)+2 log n -2 ·Θ(2 2 )+…+ 2 0 ·Θ(n) = nΘ(1)+n/2Θ(2)+n/4Θ(4)+…+1Θ(n) = Θ(n log n) 47

48 Più precisamente… 1.Nel caso peggiore, il MS esegue (n log n - 2 log n + 1) confronti, che corrisponde ad un numero compreso tra (n log n - n + 1) e (n log n + n + O(log n)) 2.Nel caso medio, il MS esegue (n log n - 2 log n + 1) – ·n confronti 3.Nel caso migliore (array già ordinato), il MS esegue n-1 confronti 48

49 Osservazioni finali Il MergeSort è un algoritmo (asintoticamente) ottimo rispetto al numero di confronti eseguiti nel caso peggiore Il MergeSort non ordina in loco, e utilizza memoria ausiliaria (loccupazione di memoria finale è pari a 2n) 49


Scaricare ppt "Didattica dei Fondamenti dellInformatica 2 Seconda giornata: progettare un algoritmo corretto, efficiente, e possibilmente ottimo! Guido Proietti Email:"

Presentazioni simili


Annunci Google