Guido Proietti Email: [email protected] URL: di.univaq.it/~proietti/index_personal

49
Didattica dei Fondamenti dell’Informatica 2 Seconda giornata: progettare un algoritmo corretto, efficiente, e possibilmente ottimo! Guido Proietti Email: [email protected] URL: www.di.univaq.it/~proietti/index_ personal 1

description

Didattica dei Fondamenti dell’Informatica 2 Seconda giornata : progettare un algoritmo corretto, efficiente, e possibilmente ottimo!. Guido Proietti Email: [email protected] URL: www.di.univaq.it/~proietti/index_personal. - PowerPoint PPT Presentation

Transcript of Guido Proietti Email: [email protected] URL: di.univaq.it/~proietti/index_personal

Page 1: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

Didattica dei Fondamenti dell’Informatica 2

Seconda giornata: progettare un algoritmo corretto, efficiente, e possibilmente ottimo!

Guido ProiettiEmail: [email protected]

URL: www.di.univaq.it/~proietti/index_personal

1

Page 2: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

Richiamo: Complessità computazionale di un algoritmo e di un problema

DefinizioneUn 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 dell’algoritmo sulle istanze di ingresso di dimensione n che comportano più lavoro per l’algoritmo stesso (ovvero, T(n) misura il caso peggiore dell’algoritmo)

DefinizioneUn problema P ha una complessità computazionale O(f(n)) se esiste un algoritmo che risolve P la cui complessità computazionale è O(f(n))

2

Page 3: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

Richiamo: gerarchia delle classi

Decidibili

ExpTime(ARRESTO(k))P (ricerca)

NP

NP-completi (SAT)

3

Page 4: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

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

Page 5: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

Le quattro proprietà fondamentali di un algoritmo (oltre l’efficienza)

• 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

Page 6: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

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

Page 7: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

Analisi di algoritmi Correttezza:

– dimostrare formalmente che un algoritmo è corretto

Complessità:– Stimare la quantità di risorse (tempo e

memoria) necessarie all’algoritmo– stimare il più grande input gestibile in tempi

ragionevoli– confrontare due algoritmi diversi– ottimizzare le parti “critiche”

7

Page 8: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

f(n) = (g(n)) se due costanti c>0 e n0≥0 tali che f(n) ≥ c g(n) per ogni n ≥ n0

Notazione asintotica

n0 n

f(n) = ( g(n) )f(n)

c g(n)

8

Page 9: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

Esempi

• Sia f(n) = 2n2 - 5n; vogliamo dimostrare che f(n)=(n2).

f(n)/n2 = (2n2 - 5n)/n2 = 2 - 5/n

ma 2 - 5/n ≥ 1 per n ≥ 5

quindi basta scegliere c=1 e n0=5 e avremo che

2n2 - 5n ≥ 1n2 per n ≥ n0=5.

• f(n) = (n) (c=1, n0=2)

• f(n) =(log n) (c=1, n0=2)

• Invece, f(n) (n3)

9

Page 10: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

Legame con il concetto di limite

ngnf ngnf

limn 0

0 ngnf

lim ngnf n

0 esiste) (se ngnf

lim ngnf n

10

Page 11: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

f(n) = (g(n)) se tre costanti c1,c2>0 e n0≥0 tali che c1 g(n) ≤ f(n) ≤ c2 g(n) per ogni n ≥ n0

Notazione asintotica

n0 n

f(n) = ( g(n) )f(n)

c1 g(n)

c2 g(n)

11

Page 12: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

Relazioni tra O, Ω e Θ

ngOnf g(n) nf

ngΘnf g(n)O nf

ngnf g(n) nf

ngΘnf g(n) nf

ngOnf e ngnf g(n) nf

12

Page 13: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

• Sia tempo(I) il tempo di esecuzione di un algoritmo sull’istanza I

Tbest(n) = min istanze I di dimensione n tempo(I)

• Intuitivamente, Tbest(n) è il tempo di esecuzione sulle istanze di ingresso che comportano meno lavoro per l’algoritmo

Caso migliore di un algoritmo

13

Page 14: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

• Sia P(I) la probabilità di occorrenza del-l’istanza I

Tavg(n) = ∑ istanze I di dimensione n P(I) tempo(I)

• Intuitivamente, Tavg(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

Page 15: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

Dato un insieme S di n elementi presi da undominio totalmente ordinato, ordinare S

IL problema: l’ordinamento

• Esempi: ordinare una lista di nomi alfabeticamente, o un insieme di numeri, o un insieme di compiti d’esame in base al cognome dello studente

• Subroutine in molti problemi

• È possibile effettuare ricerche in array ordinati in tempo O(log n) (ricerca binaria)

15

Page 16: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

Il problema dell’ordinamento(non decrescente)

• Input: una sequenza di n numeri (reali) <a1,a2,…,an>

(NOTA: la dimensione dell’input è n)

• Output: una permutazione 1,2,…,n i1,i2,…,in, ovvero un riarrangiamento <ai1

, ai2,…, ain

> della

sequenza di input in modo tale che ai1 ai2

… ain

16

Page 17: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

SelectionSort

1 2 4 5 3 7

7 2 4 5 3 1

1 2 4 5 3 7

1 2 3 5 4 7

1 2 3 4 5 7

1 2 3 4 5 7

1 2 3 4 5 7

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

17

Page 18: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

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 l’indice dell’array in cui si trova il minimo corrente

• linee 3-4: ricerca del minimo fra gli elementi A[k],…,A[n] (m viene aggiornato con l’indice dell’array in cui si trova il minimo corrente)

• linea 5: il minimo è spostato in posizione k

NOTA: Assumiamo che il primo elemento dell’array sia in A[1]

18

Page 19: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

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 dell’array

• Induzione su k:– k=1: Alla prima iterazione viene semplicemente selezionato

l’elemento minimo dell’array (i) e (ii) banalmente verificate.– k>1. All’inizio del passo k i primi k-1 elementi sono ordinati e

sono i k-1 elementi più piccoli nell’array (ipotesi induttiva). Allora la tesi segue dal fatto che l’algoritmo seleziona il minimo dai restanti n-k elementi e lo mette in posizione k. Infatti:

(ii) i primi k elementi restano i minimi nell’array(i) l’elemento in posizione k non è mai più piccolo dei primi k-1

elementi

19

Page 20: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

Complessità

temporaleSelectionSort (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 eseguitoper k=1,…, n-1

T(n) = [1+(n-k)+1]=2(n-1)+ k =2(n-1)+n·(n-1)/2 = (n2)k=1

n-1

T(n) = Tbest(n) = Tavg(n) = (n2)

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

Page 21: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

InsertionSort

2 7 4 5 3 1

7 2 4 5 3 1

2 4 7 5 3 1

2 4 5 7 3 1

2 3 4 5 7 1

1 2 3 4 5 7

Approccio incrementale: assumendo che i primi k elementi siano ordinati, estende l’ordinamento ai primi k+1 elementi, inserendo l’elemento in posizione k+1-esima nella giusta posizione rispetto ai primi k elementi

21

Page 22: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

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

Page 23: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

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: All’inizio del passo k i primi k elementi sono ordinati (ipotesi induttiva). Allora la tesi segue dal fatto che l’algoritmo inserisce A[k+1] nella giusta posizione rispetto alla sequenza A[1],…,A[k]

23

Page 24: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

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) = (n2)

j*≤k+1 confronti

k+1–j* assegnamenti

il tutto eseguitoper k=1,…, n-1

k=1

n-1

T(n) = Tbest(n) = Tavg(n) = (n2)Possiamo fare meglio?

k+1 oper.

Complessità temporale

24

1 assegnamento

Page 25: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

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 eseguitoper k=1,…, n-1tk ≤ 2k

assegnam.

tempo(n)=(n)+ tk ≤ (n)+ 2k = (n)+n·(n-1) = (n2)

tempo(n) = O(n2)

k=1

n-1

k=1

n-1

Una variante dell’IS 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

Page 26: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

Caso migliore, peggiore, e medio di InsertionSort2

• Caso migliore– array già ordinato in ordine crescente tk = 0

Tbest(n) = (n) (costo del ciclo for esterno)

• Caso peggiore– array ordinato in ordine decrescente tk = 2k

T(n) = 2k = (n2)

• Caso medio– L’elemento 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 tk = k

Tavg(n) = k = (n2)

k=1

k=1

n-1

n-1

26

Page 27: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

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 l’esecuzione della metà delle istruzioni di un ciclo, senza quindi avere un abbattimento asintotico della complessità.

27

Page 28: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

Riepilogo

Insertion Sort 2

Insertion Sort 1

Θ(n)

Caso migliore

Selection Sort Θ(n2)

Θ(n2)

Caso medio

Θ(n2)

Θ(n2)

Θ(n2)

Θ(n2)

Θ(n2)

Θ(n2)

Caso peggiore

28

Page 29: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

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 dall’algoritmo.

La complessità spaziale del Selection Sort e dell’Insertion Sort è Θ(n)

Nota: Se la complessità spaziale di un certo algoritmo è Θ(g(n)), e se tale algoritmo “ispeziona” l’intera memoria occupata, allora la complessità temporale dell’algoritmo è (g(n)), ovviamente.

29

Page 30: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

Conseguenze per il problema dell’ordinamento

La complessità spaziale di qualsiasi algoritmo che risolve il problema dell’ordinamento è (n) (dimensione input)

…ma qualsiasi algoritmo che risolve il problema dell’ordinamento deve ispezionare tutti i dati in ingresso, e quindi ha complessità temporale T(n)=(n)

Tutti gli algoritmi che risolveranno il problema dell’ordinamento avranno una complessità temporale (n)

30

Page 31: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

Delimitazioni inferiori (lower bound)DefinizioneUn 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

Page 32: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

Ottimalità di un algoritmo

DefinizioneDato 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

Page 33: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

Quindi, per il problema dell’ordinamento…

• Upper bound temporale: O(n2)– Insertion Sort, Selection Sort

• Lower bound temporale: (n)– “banale”: dimensione dell’input

Abbiamo un gap lineare tra upper bound e lower bound!

Possiamo fare meglio, ovvero abbassare l’upper bound e/o innalzare il lower bound ?

33

Page 34: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

Ordinamento per confronti

Dati due elementi ai ed aj, per determinarne l’ordinamento relativo effettuiamo una delle seguenti operazioni di confronto:

ai aj ; ai aj ; ai aj ; ai aj ; ai aj

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

Page 35: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

• 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 ai ed aj (ad esempio effettua il test ai aj);

- 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 l’ordinamento

35

Page 36: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

• Descrive le diverse sequenze di confronti che A esegue su un’istanza <a1,a2,…,an> di lunghezza n; i movimenti dei dati e tutti gli altri aspetti dell’algoritmo vengono ignorati

• Nodo interno (non foglia): i:j (modella il confronto tra ai e aj)• Nodo foglia: i1,i2,…,in (modella una risposta (output) dell’algoritmo, ovvero

una permutazione <ai1,ai2

,…,ain> degli elementi)

• L’albero di decisione è associato ad un algoritmo e alla dimensione n dell’istanza

Albero di decisione

36

Page 37: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

Esempio

2:3

1,2,3 1:3 2,1,3 2:3

1:3

1:2

1,3,2 2,3,13,1,2 3,2,1

Š

Š Š

Š Š

Input <a1,a2,a3> Riconoscete l’algoritmo associato?

È proprio l’Insertion Sort 2!

Esercizio per casa: costruire l’albero di decisione per il SS su una sequenza di 3 elementi.

37

Page 38: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

• Per una particolare istanza, i confronti eseguiti da A su quella istanza rappresentano un cammino radice – foglia

• L’algoritmo segue un cammino diverso a seconda delle caratteristiche dell’input– Caso peggiore: cammino più lungo

– Caso migliore: cammino più breve

• Il numero di confronti nel caso peggiore è pari all’altezza dell’albero di decisione (ovvero alla lunghezza, in termini di numero di archi, del più lungo cammino radice-foglia)

Proprietà

38

Page 39: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

Lemma: Un albero strettamente binario (ovvero, in cui ogni nodo interno ha esattamente due figli) con k foglie ha altezza h(k) log2 k.

Dim: Dimostrazione per induzione su k:– Caso base k=1 (albero-nodo ): banale h(k)=0≥ log21=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+log2(k/2)

=1+log2k-log22=log2k. QED

Altezza in funzione delle foglie

39

Page 40: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

• Consideriamo l’albero di decisione di un qualsiasi algoritmo che risolve il problema dell’ordinamento di n elementi

• Tale albero deve avere almeno n! foglie: infatti, se l’algoritmo è corretto, deve contemplare tutti i possibili output, ovvero le n! permutazioni della sequenza di n elementi in input

• Dal lemma precedente, avremo che l’altezza h(n) dell’albero di decisione sarà:

Il lower bound (n log n)

h(n) log2(#foglie) log2(n!)

Formula di Stirling:

n! (2n)1/2 ·(n/e)n

> (n/e)n

> log2 (n/e)n =

= n log2 (n/e)

= n log2 n – n log2 e

=

= (n log n) QED

=

40

Page 41: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

• Problema dell’ordinamento:

– Lower bound - (n log n) albero di decisione

– Upper bound – O(n2) IS,SS

• Proviamo a costruire un algoritmo ottimo, usando la tecnica del divide et impera:1 Divide: dividi l’array a metà2 Risolvi il sottoproblema ricorsivamente3 Impera: fondi le due sottosequenze ordinate

Un algoritmo ottimo: il MergeSort (John von Neumann, 1945)

41

Page 42: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

Esempio di esecuzione

7 2 4 5 3 1 5 6

7 2 4 5 3 1 5 6

7 2 4 5 3 1 5 6

7 2 4 5 3 1 5 6

1 2 3 4 5 5 6 7

2 4 5 7 1 3 5 6

2 7 4 5 1 3 5 6

7 2 4 5 3 1 5 6

input

output

Input ed

output delle

chiamate

ricorsive

42

Page 43: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

• Due array ordinati A e B possono essere fusi rapidamente:– estrai ripetutamente il minimo di A e B e copialo

nell’array di output, finché A oppure B non diventa vuoto

– copia gli elementi dell’array non ancora completamente svuotato alla fine dell’array 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

Page 44: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

Merge (A, i1, f1, f2)

1. Sia X un array ausiliario di lunghezza f2-i1+1

2. i=1

3. i2=f1+1

4. while (i1 f1 e i2 f2) do

5. if (A[i1] A[i2])

6. then X[i]=A[i1]

7. incrementa i e i1

8. else X[i]=A[i2]

9. incrementa i e i2

10. if (i1<f1) then copia A[i1;f1] alla fine di X

11. else copia A[i2;f2] alla fine di X

12. copia X in A[i1;f2]

fonde A[i1;f1] e A[f1+1;f2] output in A[i1;f2]

Osservazione: usa l’array ausiliario X

Algoritmo di fusione di sequenze ordinate

44

Page 45: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

LemmaLa procedure Merge fonde due sequenze ordinate di lunghezza n1 e n2 eseguendo al più n1+ n2 -1 confrontiDim: Ogni confronto “consuma” un elemento di A.Nel caso peggiore tutti gli elementi tranne l’ultimo sonoaggiunti alla sequenza X tramite un confronto.Il numero totale di elementi è n1+ n2. Quindi il numero totaledi confronti è n1+ n2 -1. QED

Numero di confronti: C(n=n1+ n2)=O(n1+ n2)=O(n)(si noti che vale anche C(n)=Ω(minn1,n2))

Numero di operazioni (confronti + copie)? T(n)=(n1+ n2)

Costo dell’algoritmo di merge

45

Page 46: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

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

Page 47: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

Complessità del MergeSortSi 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/22)+Θ(n/2))+Θ(n)=

=2(2(2T(n/23)+Θ(n/22))+Θ(n/2))+Θ(n)=…

e per k = log2n si ha n/2k = 1 e quindi

T(n)=2(2(…(2T(n/2k)+Θ(1))+…+Θ(n/22))+Θ(n/2))+Θ(n)

= 2log n·Θ(1)+2log n-1·Θ(2)+2log n-2·Θ(22)+…+ 20·Θ(n)

= n∙Θ(1)+n/2∙Θ(2)+n/4∙Θ(4)+…+1∙Θ(n) = Θ(n log n)47

Page 48: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

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) – 0.2645·n confronti

3. Nel caso migliore (array già ordinato), il MS esegue n-1 confronti

48

Page 49: Guido Proietti Email: guido.proietti@univaq.it URL:  di.univaq.it/~proietti/index_personal

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 (l’occupazione di memoria finale è pari a 2n)

49