Complessità e ordinamento di Ezio Sperduto

Post on 21-Dec-2014

1.346 views 2 download

description

 

Transcript of Complessità e ordinamento di Ezio Sperduto

Complessità e Ordinamento

Ezio Sperduto

Notazioni Asintotiche

grandi O(…) Ω(…) Θ(…)

piccole o(…) ω(…)piccole o(…) ω(…)

definiscono ordini di grandezza delle funzioni

Notazioni Asintotiche

parametro n: dimensione dell’input

T(n)=O(n2)T(n)=O(n2)

Complessità temporale Classe delle funzioni

quadratiche

Notazioni Asintotiche

Formalmente:

f(n) ∈ O(g(n))∈

O(g(n)) =

h(n): ∃x0, c t.c. ∀n≥x0 ⇒ 0 ≤ h(n) ≤ c·g(n)

Notazioni Asintotiche

(a) f(n) è stretta tra c1·g(n) e c2·g(n) Θ(g(n))

(b) f(n) è spinta sotto la funzione c·g(n) O(g(n))

(c) f(n) è spinta sopra la funzione c·g(n) Ω(g(n))

Notazioni Asintotiche

Θ(n)

Θ(n log n)

Θ(n2)

Θ(log n)

Gli ordini di grandezza identificano delle

CLASSI di COMPLESSITA’

Scrivere T(n)=O(log n) equivale a scrivere “correttamente” T(n) ∈ O(log n)

Notazioni Asintotiche

Notazioni grandi e notazioni piccole:

f(n)=O(g(n)) f(n) ≤ classe di g(n)

la notazione O-grande indica un limite superiore non strettola notazione O-grande indica un limite superiore non stretto

f(n)=o(g(n)) f(n) < classe di g(n)

la notazione O-piccola indica un limite superiore stretto

Complessità Temporale

Classi di complessità asintotica più note:

O(1) costante

O(logn) logaritmico

O(n) lineare

O(nlogn) log-lineareO(nlogn) log-lineare

O(n2) quadratico

O(n3) cubico

O(n4) ….. polinomiali superiori

O(cn) esponenziale

O(n!) super-esponenziale

Ordinamento

Input: a1, a2,…,an

sequenza di valori (interi) non-ordinata

Output: a’1, a’2,…,a’n

permutazione ordinata dei valori in input

Ordinamento

La tecnica di ordinamento varia in base agli

elementi da ordinare:

- valori

- strutture/oggetti con attributo discriminante- strutture/oggetti con attributo discriminante

La tecnica di ordinamento varia in base alla

struttura contenitore:

- array / blocco di memoria ad accesso costante

- lista collegata di elementi

HeapSort

Basato su struttura Heap: albero binario con 2 proprietà

- Heap property: un nodo contiene un valore

maggiore dei sottoalberimaggiore dei sottoalberi

- shape property: albero completo tranne

ultimo livello

altezza dell’albero O(logn)

HeapSort

Heap property

HeapSort

Implementazione mediante vettore, per livelli:

left(i) = 2*i

right(i) = 2*i + 1

HeapSort

Operazione Heapify:

- input: nodo v dell’heap

(assunto: i sottoalberi sono heap)

- output: il sottoalbero su v è un heap

(il valore di v potrà essere scambiato con i valori

nei sottoalberi)

HeapSort

void heapify(int[] h, int i)

int sx=left(i);

int dx=right(i);

int m=indMax(h, sx, dx, i);

complessità:

O(logn)applicato alla radice

int m=indMax(h, sx, dx, i);

if(i != m)

swapValue(h,i,m);

heapify(h,m)

HeapSort

void buildHeap(int[] h)

for(int i=h.length/2; i>=0; i--)

heapify(h,i);

complessità:

O(n)analisi ammortizzata

Applico heapify a tutti i nodi con figli dell’heap.

Partendo dall’ultimo, fino al primo.

HeapSort

void heapSort(int[] h)

buildheap(h); O(n)

for(int i=h.length-1; i<=1;i--) O(n)for(int i=h.length-1; i<=1;i--) O(n)

swapValue(h,0,i); O(1)

heapify(h,0,i-1); O(logn)

Il terzo parametro nell’heapify diminuisce la dimensione.

Complessità: O(nlogn)

HeapSort

Caso peggiore: O(nlogn)

Caso migliore: O(nlogn)

Caso medio: O(nlogn)

Complessità spaziale: O(1)

Stabile: no

In place: si

QuickSort

void quickSort(int[] a, int n1, int n2)

if(n1<n2)

p=partition(a,n1,n2);

quickSort(a,n1,p);

quickSort(a,p+1,n2);

QuickSortMetodo partition (versione di Hoare):

int partition(int[] a, int n1, int n2)

int x=a[n1];

int i=n1-1;

int j=n2+1;

while(true)

vettore a

Pivot

valori ≤valori ≥

i j

while(true)

do j--; while(!(a[j]<=x));

do i++; while(!(a[i]>=x));

if(i<j)

swap(A,i,j);

else

return j;

QuickSort

Caso peggiore: O(n2)

Caso migliore: O(nlogn)

Caso medio: O(nlogn)

Complessità spaziale: O(logn)

Stabile: no

In place: si

OrdinamentoAlgoritmo Peggiore Medio Migliore Memoria Stabile In Place

CountingSort O(n+k) O(n+k) O(n+k) O(n+k) SI NO

HeapSort O(nlogn) O(nlogn) O(nlogn) O(1) NO SI

QuickSort(2) O(nlogn) O(nlogn) O(nlogn) O(nlogn) NO SI

MergeSort O(nlogn) O(nlogn) O(nlogn) O(n) SI NO

SelectionSort O(n2) O(n2) O(n2) O(1) NO SISelectionSort O(n ) O(n ) O(n ) O(1) NO SI

InsertionSort O(n2) O(n2) O(n) O(1) SI SI

BubbleSort O(n2) O(n2) O(n) O(1) SI SI

QuickSort(1) O(n2) O(nlogn) O(nlogn) O(nlogn) NO SI

StupidSort Illimitato O(n*n!) O(n) O(n) NO SI

Ordinamento

java.util.Arrays.sort(…)

The sorting algorithm is a Dual-Pivot Quicksort by

Vladimir Yaroslavskiy, Jon Bentley, and JoshuaVladimir Yaroslavskiy, Jon Bentley, and Joshua

Bloch. This algorithm offers O(n log(n))

performance on many data sets that cause other

quicksorts to degrade to quadratic performance,

and is typically faster than traditional (one-pivot)

Quicksort implementations.

Ordinamento

OpenJDK: java.util.Arrays.sort(…)private static void sort1(int x[], int off, int len)

// Insertion sort on smallest arrays

if (len < 7)

// Choose a partition element, v

// Establish Invariant: v* (<v)* (>v)* v*

// Swap partition elements back to middle

// Recursively sort non-partition-elements

Ordinamentojava.util.Collections.sort(…)• Implementation note: This implementation is a stable, adaptive, iterative mergesort that

requires far fewer than n lg(n) comparisons when the input array is partially sorted, while

offering the performance of a traditional mergesort when the input array is randomly

ordered. If the input array is nearly sorted, the implementation requires approximately n

comparisons. Temporary storage requirements vary from a small constant for nearly sorted

input arrays to n/2 object references for randomly ordered input arrays.

• The implementation takes equal advantage of ascending and descending order in its input • The implementation takes equal advantage of ascending and descending order in its input

array, and can take advantage of ascending and descending order in different parts of the

same input array. It is well-suited to merging two or more sorted arrays: simply concatenate

the arrays and sort the resulting array.

• The implementation was adapted from Tim Peters's list sort for Python (TimSort). It uses

techiques from Peter McIlroy's "Optimistic Sorting and Information Theoretic Complexity", in

Proceedings of the Fourth Annual ACM-SIAM Symposium on Discrete Algorithms, pp 467-

474, January 1993.

• This implementation dumps the specified list into an array, sorts the array, and iterates over

the list resetting each element from the corresponding position in the array. This avoids the

n2 log(n) performance that would result from attempting to sort a linked list in place.