Algoritmi e Strutture Dati Capitolo 4 Ordinamento Algoritmi e strutture dati Luigi Laura Ordinamento Dato un insieme S di n oggetti presi da un dominio totalmente ordinato, ordinare S • Esempi: ordinare alfabeticamente lista di nomi, o insieme di numeri, o insieme di compiti d’esame in base a cognome studente • Subroutine di molti problemi • E’ possibile effettuare ricerche in array ordinati in tempo O(log n) 2 da Demetrescu et al. McGraw Hill 2004 Algoritmi e strutture dati Luigi Laura Algoritmi e tempi tipici • Numerosi algoritmi • Tre tempi tipici: O(n2), O(n log n), O(n) n 10 100 n log2 n ~ 33 ~ 665 n2 100 104 1000 106 109 ~ 104 ~ 2 · 107 ~ 3 · 1010 106 1012 1018 da Demetrescu et al. McGraw Hill 2004 3 Algoritmi e strutture dati Luigi Laura Algoritmi di ordinamento 4 da Demetrescu et al. McGraw Hill 2004 Algoritmi e strutture dati Luigi Laura SelectionSort Approccio incrementale. Estende ordinamento da k a (k+1) elementi, scegliendo minimo tra (n-k) elementi non ancora ordinati e mettendolo in posizione (k+1) da Demetrescu et al. McGraw Hill 2004 5 Algoritmi e strutture dati Luigi Laura SelectionSort: analisi k - esima estrazione di minimo costa tempo O(n-k) In totale, il tempo di esecuzione è: n-1 ∑ O(n-k) k=1 n-1 = O ( ∑ i) = O(n ) 2 i=1 [ cambiamento di variabile (i = n – k) e serie aritmetica ] 6 da Demetrescu et al. McGraw Hill 2004 Algoritmi e strutture dati Luigi Laura InsertionSort Approccio incrementale. Estende ordinamento da k a (k+1) elementi, posizionando elemento (k+1)-esimo nella posizione corretta rispetto ai primi k elementi da Demetrescu et al. McGraw Hill 2004 7 Algoritmi e strutture dati Luigi Laura InsertionSort: analisi Inserimento del k-esimo elemento nella posizione corretta rispetto ai primi k richiede tempo O(k) nel caso peggiore In totale, il tempo di esecuzione è : n-1 O ( ∑ k) = O(n ) 2 k=1 [ serie aritmetica ] 8 da Demetrescu et al. McGraw Hill 2004 Algoritmi e strutture dati Luigi Laura BubbleSort • Esegue una serie di scansioni dell’array – In ogni scansione confronta coppie di elementi adiacenti, scambiandoli se non sono nell’ordine corretto – Dopo una scansione in cui non viene effettuato nessuno scambio l’array è ordinato • Dopo la k-esima scansione, i k elementi più grandi sono correttamente ordinati ed occupano le k posizioni più a destra correttezza e tempo 2 di esecuzione O(n ) 9 Algoritmi e strutture dati da Demetrescu et al. McGraw Hill 2004 Luigi Laura Esempio di esecuzione 10 da Demetrescu et al. McGraw Hill 2004 Algoritmi e strutture dati Luigi Laura O( n2 ) è quanto di peggio si possa fare: tutti i confronti possibili! Possiamo fare di meglio ? da Demetrescu et al. McGraw Hill 2004 11 Algoritmi e strutture dati Luigi Laura 1. QuickSort 2. MergeSort 3. HeapSort 12 da Demetrescu et al. McGraw Hill 2004 Algoritmi e strutture dati Luigi Laura QuickSort • Usa la tecnica del divide et impera: 1 Divide: scegli un elemento x della sequenza (pivot) e partiziona la sequenza in elementi ≤ x ed elementi > x 2 Risolvi i due sottoproblemi ricorsivamente 3 Impera: restituisci la concatenazione delle due sottosequenze ordinate da Demetrescu et al. McGraw Hill 2004 13 Algoritmi e strutture dati Luigi Laura Partizione in loco • Scorri l’array “in parallelo” da sinistra verso destra e da destra verso sinistra – da sinistra verso destra, ci si ferma su un elemento maggiore del pivot – da destra verso sinistra, ci si ferma su un elemento minore del pivot • Scambia gli elementi e riprendi la scansione Tempo di esecuzione: O(n) 14 da Demetrescu et al. McGraw Hill 2004 Algoritmi e strutture dati Luigi Laura Partizione in loco: un esempio da Demetrescu et al. McGraw Hill 2004 15 Algoritmi e strutture dati Luigi Laura Analisi nel caso peggiore • Nel caso peggiore, il pivot scelto ad ogni passo è il minimo o il massimo degli elementi nell’array • Il numero di confronti nel caso peggiore è : C(n) = C(n-1) + O(n) • Risolvendo per iterazione si ottiene C(n) = O(n2) 16 da Demetrescu et al. McGraw Hill 2004 Algoritmi e strutture dati Luigi Laura Esempio di esecuzione L’albero delle chiamate ricorsive può essere sbilanciato da Demetrescu et al. McGraw Hill 2004 17 Algoritmi e strutture dati Luigi Laura Randomizzazione • Possiamo evitare il caso peggiore scegliendo come pivot un elemento a caso • Poiché ogni elemento ha la stessa probabilità, pari a 1/n, di essere scelto come pivot, il numero di confronti nel caso atteso è: n-1 C(n)= ∑ a=0 n-1 1 n-1+C(a)+C(n-a-1) = n-1+ ∑ 2 C(a) n n a=0 dove a e (n-a-1) sono le dimensioni dei sottoproblemi risolti ricorsivamente 18 da Demetrescu et al. McGraw Hill 2004 Algoritmi e strutture dati Luigi Laura Analisi nel caso medio n-1 La relazione di ricorrenza C(n)= n-1+ ∑ 2n C(a) ha soluzione C(n) ≤ 2 n log n a=0 Dimostrazione per sostituzione Assumiamo per ipotesi induttiva che C(i) ≤ 2 i log i n-1 C(n)≤ n-1+ ∑ 2 2 i log i ≤ n-1+ 2 n n i=0 n ∫2 x log x dx Integrando per parti si dimostra che C(n) ≤ 2 n log n da Demetrescu et al. McGraw Hill 2004 19 Algoritmi e strutture dati Luigi Laura MergeSort Usiamo la tecnica del divide et impera: 1 Divide: dividi l’array a metà 2 Risolvi il sottoproblema ricorsivamente 3 Impera: fondi le due sottosequenze ordinate Rispetto a QuickSort, divide semplice ed impera complicato 20 da Demetrescu et al. McGraw Hill 2004 Algoritmi e strutture dati Luigi Laura Fusione (Merge) • 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 vuoto alla fine dell’array di output • Tempo: O(n), dove n è il numero totale di elementi da Demetrescu et al. McGraw Hill 2004 21 Algoritmi e strutture dati Luigi Laura Mergesort: esempio di esecuzione Input ed output delle chiamate ricorsive 22 da Demetrescu et al. McGraw Hill 2004 Algoritmi e strutture dati Luigi Laura Tempo di esecuzione • Numero di confronti del MergeSort descritto da relazione di ricorrenza: C(n) = 2 C(n/2) + O(n) • Da Teorema Master si ottiene la soluzione C(n) = O(n log n) da Demetrescu et al. McGraw Hill 2004 23 Algoritmi e strutture dati Luigi Laura HeapSort • Stesso approccio incrementale del SelectionSort • Usa però struttura dati più efficiente per estrarre massimo ad ogni iterazione • Struttura dati heap associata ad insieme S : albero binario radicato con le seguenti proprietà: 1) completo fino al penultimo livello 2) elementi di S memorizzati nei nodi dell’albero 3) chiave(padre(v)) ≥ chiave(v) per ogni nodo v 24 da Demetrescu et al. McGraw Hill 2004 Algoritmi e strutture dati Luigi Laura Struttura dati heap Rappresentazione ad albero e con vettore posizionale sin(i) = 2i des(i) = 2i+1 da Demetrescu et al. McGraw Hill 2004 25 Algoritmi e strutture dati Luigi Laura Heap con struttura rafforzata Le foglie nell’ultimo livello sono compattate a sinistra Il vettore posizionale ha esattamente dimensione n 26 da Demetrescu et al. McGraw Hill 2004 Algoritmi e strutture dati Luigi Laura Proprietà salienti degli heap 1) Il massimo è contenuto nella radice 2) L’albero ha altezza O(log n) 3) Gli heap con struttura rafforzata possono essere rappresentati in un array di dimensione n da Demetrescu et al. McGraw Hill 2004 27 Algoritmi e strutture dati Luigi Laura La procedura fixHeap Se tutti i nodi di H tranne v soddisfano la proprietà di ordinamento a heap, possiamo ripristinarla come segue: fixHeap(nodo v, heap H) if (v è una foglia) then return else sia u il figlio di v con chiave massima if ( chiave(v) < chiave(u) ) then scambia chiave(v) e chiave(u) fixHeap(u,H) Tempo di esecuzione: O(log n) 28 da Demetrescu et al. McGraw Hill 2004 Algoritmi e strutture dati Luigi Laura Estrazione del massimo • Copia nella radice la chiave contenuta nella la foglia più a destra dell’ultimo livello • Rimuovi la foglia • Ripristina la proprietà di ordinamento a heap richiamando fixHeap sulla radice Tempo di esecuzione: O(log n) da Demetrescu et al. McGraw Hill 2004 29 Algoritmi e strutture dati Luigi Laura Costruzione dell’heap Algoritmo ricorsivo basato su divide et impera heapify(heap H) if (H è vuoto) then return else heapify(sottoalbero sinistro di H) heapify(sottoalbero destro di H) fixHeap(radice di H,H) Tempo di esecuzione: T(n) = 2 T(n/2) + O(log n) T(n) = O(n) 30 dal Teorema Master da Demetrescu et al. McGraw Hill 2004 Algoritmi e strutture dati Luigi Laura HeapSort • Costruisci un heap tramite heapify • Estrai ripetutamente il massimo per (n-1) volte O(n) O(n log n) – ad ogni estrazione memorizza il massimo nella posizione dell’array che si è appena liberata ordina “in loco” in tempo O(n log n) 31 da Demetrescu et al. McGraw Hill 2004 Algoritmi e strutture dati Luigi Laura Possiamo fare meglio di O(n log n)? 32 da Demetrescu et al. McGraw Hill 2004 Algoritmi e strutture dati Luigi Laura Lower bound • Dimostrazione (matematica) che non possiamo andare più veloci di una certa quantità • Più precisamente, ogni algoritmo all’interno di un certo modello di calcolo deve avere tempo di esecuzione almeno pari a quella quantità • Non significa necessariamente che non è possibile fare di meglio • Potrebbe essere possibile fare di meglio al di fuori di quel modello 33 da Demetrescu et al. McGraw Hill 2004 Algoritmi e strutture dati Luigi Laura Lower bound • Delimitazione inferiore: quantità di risorsa necessaria per risolvere un determinato problema • Dimostrare che Ω(n log n) è lower bound al numero di confronti richiesti per ordinare n oggetti. • Come? • Dobbiamo dimostrare che tutti gli algoritmi richiedono Ω(n log n) confronti! 34 da Demetrescu et al. McGraw Hill 2004 Algoritmi e strutture dati Luigi Laura Modello basato su confronti • In questo modello, per ordinare è possibile usare solo confronti tra oggetti • Primitive quali operazioni aritmetiche (somme o prodotti), logiche (and e or), o altro (shift) sono proibite • Sufficientemente generale per catturare le proprietà degli algoritmi più noti da Demetrescu et al. McGraw Hill 2004 35 Algoritmi e strutture dati Luigi Laura Come dimostrare lower bound • Consideriamo un qualsiasi algoritmo A, che ordina solo mediante confronti • Non abbiamo assolutamente idea di come funziona A ! • Ciò nonostante, dimostreremo che A deve eseguire almeno Ω(n log n) confronti • Dato che l’unica ipotesi su A è che ordini mediante confronti, il lower bound sarà valido per tutti gli algoritmi basati su confronti! 36 da Demetrescu et al. McGraw Hill 2004 Algoritmi e strutture dati Luigi Laura Alberi di decisione • Strumenti per rappresentare algoritmi di ordinamento • Descrivono sequenza di confronti che un algoritmo esegue su istanze di lunghezza n 37 da Demetrescu et al. McGraw Hill 2004 Algoritmi e strutture dati Luigi Laura Alberi di decisione = algoritmi basati su confronti! • Ogni algoritmo basato su confronti può essere rappresentato da un albero di decisione: – confronti scelti dall’algoritmo possono dipendere solo dagli esiti dei confronti precedenti! • Un albero di decisione può essere “letto” come algoritmo basato su confronti: – per ogni input, il cammino nell’albero descrive confronti da effettuare e permutazione che produce soluzione 38 da Demetrescu et al. McGraw Hill 2004 Algoritmi e strutture dati Luigi Laura Proprietà alberi di decisione • Per una particolare istanza, i confronti eseguiti da A su quella istanza sono rappresentati da un cammino radice - foglia • Il numero di confronti nel caso peggiore è pari all’altezza dell’albero di decisione • Un albero di decisione per l’ordinamento di n elementi contiene almeno (n!) foglie (una per ogni possibile permutazione degli n oggetti) da Demetrescu et al. McGraw Hill 2004 39 Algoritmi e strutture dati Luigi Laura Lower bound • Un albero binario con k foglie tale che ogni nodo interno ha esattamente due figli ha altezza almeno log2 k • Dimostrazione per induzione su k: – Passo base: 0 ≥ log2 1 – h(k) ≥ 1 + h(k/2) poiché uno dei due sottoalberi ha almeno metà delle foglie – h(k/2) ≥ log2 (k/2) per ipotesi induttiva – h(k) ≥ 1 + log2 (k/2) = log2 k 40 da Demetrescu et al. McGraw Hill 2004 Algoritmi e strutture dati Luigi Laura Il lower bound Ω (n log n) • L’albero di decisione ha almeno n! foglie • La sua altezza è almeno log2 (n!) • Formula di Stirling: n! ≥ (2πn)1/2 · (n/e) n • Quindi: log2 (n!) = Ω (n log n) da Demetrescu et al. McGraw Hill 2004 41 Algoritmi e strutture dati Luigi Laura Ordinamenti lineari (per dati con proprietà particolari) 42 da Demetrescu et al. McGraw Hill 2004 Algoritmi e strutture dati Luigi Laura Sappiamo che gli n elementi da ordinare sono tutti distinti e nell’intervallo [1,n] In quanto tempo possiamo ordinarli? O(1) Contraddice il lower bound? No. Perché? da Demetrescu et al. McGraw Hill 2004 43 Algoritmi e strutture dati Luigi Laura IntegerSort: fase 1 Meno banale: ordinare n interi con valori in [1,k] Mantieni array Y di k contatori tale che Y[x] = numero di occorrenze di x 44 da Demetrescu et al. McGraw Hill 2004 Algoritmi e strutture dati Luigi Laura IntegerSort: fase 2 Scandisci Y da sinistra verso destra. Se Y[x] = k, scrivi in X il valore x per k volte da Demetrescu et al. McGraw Hill 2004 45 Algoritmi e strutture dati Luigi Laura IntegerSort: analisi • O(k) per inizializzare contatori a 0 • O(n) per calcolare valori dei contatori • O(n + k) per ricostruire sequenza ordinata O(n + k) Tempo lineare se k = O(n) 46 da Demetrescu et al. McGraw Hill 2004 Algoritmi e strutture dati Luigi Laura BucketSort Per ordinare n record con chiavi intere in [1,k] • Basta mantenere un array di liste, anziché di contatori, ed operare come per IntegerSort • La lista Y[x] conterrà gli elementi con chiave uguale a x • Concatenare poi le liste Tempo O(n + k) come per IntegerSort 47 Algoritmi e strutture dati da Demetrescu et al. McGraw Hill 2004 Luigi Laura Stabilità • Un algoritmo è stabile se preserva ordine iniziale tra elementi uguali (stessa chiave) • QuickSort è stabile se la partizione lo rende stabile • MergeSort è stabile se divisione lo rende stabile (pari e dispari non lo rende stabile) • HeapSort non è stabile • BucketSort può essere reso stabile appendendo gli elementi di X in coda alla opportuna lista Y[i] 48 da Demetrescu et al. McGraw Hill 2004 Algoritmi e strutture dati Luigi Laura RadixSort • Cosa fare se k > n, ad esempio k = Θ(nc)? • Rappresentiamo gli elementi in base b, ed eseguiamo una serie di BucketSort • Procediamo dalla cifra meno significativa a quella più significativa Per b=10 2397 4368 5924 5924 2397 4368 5924 4368 2397 4368 2397 5924 2397 4368 5924 da Demetrescu et al. McGraw Hill 2004 49 Algoritmi e strutture dati Luigi Laura Correttezza • Se x e y hanno una diversa t-esima cifra, la t-esima passata di BucketSort li ordina • Se x e y hanno la stessa t-esima cifra, la proprietà di stabilità del BucketSort li mantiene ordinati correttamente Dopo la t-esima passata di BucketSort, i numeri sono correttamente ordinati rispetto alle t cifre meno significative 50 da Demetrescu et al. McGraw Hill 2004 Algoritmi e strutture dati Luigi Laura Tempo di esecuzione • O(logb k) passate di bucketsort • Ciascuna passata richiede tempo O(n + b) O( (n + b) logb k) Se b = Θ(n), si ha O(n logn k) = O n log k log n Tempo lineare se k = O(nc), c costante da Demetrescu et al. McGraw Hill 2004 51 Algoritmi e strutture dati Luigi Laura Riepilogo • Nuove tecniche algoritmiche: – – – – Incrementale (SelectionSort, InsertionSort) Divide et impera (MergeSort, QuickSort) Plug in di strutture dati efficienti (HeapSort) Randomizzazione (QuickSort) • Alberi di decisione per dimostrare lower bound • Sfruttare proprietà dei dati in ingresso (fuori dal modello) per progettare algoritmi più efficienti: algoritmi lineari 52 da Demetrescu et al. McGraw Hill 2004 Algoritmi e strutture dati Luigi Laura Esempio di esecuzione 53 da Demetrescu et al. McGraw Hill 2004