330 likes | 474 Views
Radix-Sort ( A , d ) // A [ i ] = c d ... c 2 c 1 for j = 1 to d // A è ordinato rispetto alle cifre c j -1 ... c 1 “usa un algoritmo stabile per ordinare A rispetto alla j -esima cifra” // A è ordinato rispetto alle cifre c j ... c 1
E N D
Radix-Sort(A,d) // A[i]= cd...c2c1 forj= 1 tod // A è ordinatorispetto alle cifre cj-1...c1 “usa un algoritmo stabile per ordinare A rispetto alla j-esima cifra” // A è ordinatorispetto alle cifre cj...c1 // A è ordinato
Radix-Sort(A,d) // Complessità forj= 1 tod “usa Counting-Sort per ordinare A rispetto alla j-esima cifra” Complessità: dove b è la base della numerazione e d è il numero di cifre dei numeri da ordinare.
Dovendo ordinare n numeri di m bit ciascuno possiamo scegliere r < m e suddividere i numeri in d=m/r “cifre” di r bit ciascuna In questo caso la base della numerazione è b=2r e Radix-Sortrichiede tempo La funzione ha un minimo per r tale che Quindi il valore ottimo di r dipende soltanto da n ed è approssimativamente log2 n.
Algoritmo Bucket-Sort L’algoritmo Bucket-Sort assume che i valori da ordinare siano dei numeri reali in un intervallo semiaperto [a,b). Per semplicità di esposizione assumiamo che l’intervallo sia [0,1).
Bucket-Sort per ordinare l’array A procede come segue: • Divide [0,1) in n parti uguali e inizializza un arrayB[0..n-1] di liste vuote (i bucket) • Mette in ciascuna lista B[k] gli elementi A[i] che cadono nella k-esima parte di [0,1) • Ordina ciascuna lista • Ricopia in A tutti gli elementi delle liste nell’ordine B[0],B[1],…,B[n-1]
1 2 3 4 5 6 7 8 9 10 B / / / / / / / / / / 2 0 1 6 9 4 7 3 5 8 .12 / .17 / .21 / .23 / .26 / .68 .26 .39 .39 .78 .94 .68 .17 .94 / / / / / / / / / .21 .72 .12 .23 / / / / .72 / .78 / 1 2 3 4 5 6 7 8 9 10 A .12 .17 .21 .23 .26 .39 .68 .72 .78 .94 A .78 .17 .39 .26 .72 .94 .21 .12 .23 .68
Bucket-Sort(A) n= A.length fori= 0 ton-1 “crea la lista vuota B[i]” fori= 1 ton “metti A[i] nella lista B[ nA[i] ]” // Gli elementi dell’arrayA sono stati tutti // inseriti nelle liste B[0],B[1],...,B[n-1] // Gli elementi di una lista B[i] sono minori degli // elementi della lista successiva B[i+1] fori= 0 ton-1 “ordina la lista B[i]” “copia in A le liste B[0],B[1],...,B[n-1]” // A è ordinato
Bucket-Sort(A) // Complessità n= A.length// fori= 0 ton-1 “crea la lista vuota B[i]” // fori= 1 ton “metti A[i] nella lista B[nA[i]]” // fori= 0 ton-1 “ordina la lista B[i] con InsertSort” // “copia in A le liste B[0],...,B[n-1]” //
Nel caso peggiore in cui tutti gli elementi vanno a finire in un’unica lista abbiamo: Nel caso migliore in cui gli elementi si distribuiscono uno per lista abbiamo: Anche per il caso medio, se si assume che i valori in ingresso siano uniformemente distribuiti nell’intervallo [0,1), si dimostra che: Per dimostrarlo ci servono alcune semplici nozioni di calcolo delle probabilità.
Supponiamo di estrarre casualmente un valore xda un insieme X di possibili valori. Non necessariamente tutti i valori xhanno la stessa probabilità di essere estratti. Indichiamo con pxla probabilità che venga estratto x Naturalmente Il valore medio che ci aspettiamo di ottenere si dice valore atteso di X ed è
Ad esempio se X è l’insieme delle possibili vincite alla roulette quando puntiamo 100 € su di un numero allora X contiene i due valori: - 3600 € con probabilità 1/37 (si vince 36 volte la posta e i numeri della roulette sono 37 contando anche lo 0 dove vince sempre il banco) e - 0 € con probabilità 36/37 Il valore atteso della vincita è allora Dunque paghiamo 100 € per ricevere in media soltanto 97,30 € !!!!
Vediamo un altro esempio: X è l’insieme delle possibili vincite al Lotto quando puntiamo 100 € su di un terno. • X contiene i due valori: • 450000 € con probabilità 1/11748 (la vincita è 4500 volte la posta e la probabilità che esca il terno è 1/11748) . • 0 € con probabilità 11747/11748. • Il valore atteso della vincita è allora Dunque paghiamo 100 € per ricevere in media soltanto 38,30 €. Gli altri 61,70 € se li tiene lo stato come tassa sulla speranza
Il valore atteso gode delle seguenti proprietà: qualunque siano le due variabili casuali X ed Y (anche se non sono tra loro indipendenti) Inoltre se le due variabili X ed Y sono indipendenti: Se c è una costante:
Tornando alla complessità media di Bucket-Sort e usando le proprietà del valore atteso: Per ragioni di simmetria il valore atteso è lo stesso per tutte le liste. Ci possiamo quindi limitare a calcolare il valore atteso relativo alla prima lista:
Per calcolare definiamo le variabili casuali indicatrici per cui Se A[i] è scelto casualmente, la variabile Xi ha valore 1 con probabilità 1/n e 0 con probabilità (n-1)/n. Il valore atteso è
Usando le variabili casuali indicatrici Xi possiamo calcolare:
Quindi, assumendo che i valori siano dei reali uniformemente distribuiti in [0,1):
Algoritmi per statistiche d’ordine Problema della statistica d’ordine Input: Un insieme A di n numeri ed un intero k compreso tra 1 ed n Output: xA, k-esimo in ordine di grandezza xA è il k-esimo in ordine di grandezza se gli altri n-1 elementi si possono ripartire in due gruppi: un gruppo di k-1 elementi tutti minori o uguali di x ed un gruppo di n-k elementi tutti maggiori o uguali di x.
Casi particolari: k = 1 (minimo) k = n (massimo) k = (n+1)/2 (mediana inferiore o mediana) k = (n+1)/2 (mediana superiore)
Minimo o massimo Quanti confronti servono per trovare il minimo (o il massimo)? Minimo(A) // Massimo(A) è analogo min=A[1] fori= 2 toA.length ifmin > A[i] min=A[i] returnmin n-1 confronti come limite superiore
Ma anche n-1 confronti come limite inferiore! Possiamo escludere che un elemento sia il minimo soltanto dopo aver verificato che esso è maggiore di un altro!! Per escludere n-1 elementi servono quindi almeno n-1 confronti. Dunque n-1 confronti è un limite stretto per calcolare il minimo e tale limite vale anche per il massimo.
Minimo e massimo Quanti confronti servono per trovare assieme il minimo e il massimo? Min-Max(A) ifA.length dispari max=min=A[1], i= 2 else ifA[1] < A[2] min=A[1], max=A[2], i= 3 else min=A[2], max=A[1], i= 3
whilei ≤A.length ifA[i] < A[i+1] ifmin > A[i] min=A[i] ifmax < A[i+1] max=A[i+1] else ifmin > A[i+1] min=A[i+1] ifmax < A[i] max=A[i] ii+2 returnmin,max
se n dispari i confronti sono: se n pari i confronti sono: meno di 3 confronti ogni 2 elementi
Statistica d’ordine in tempo medio lineare Il problema della statistica d’ordine: Input: Un insieme A di n valori ed un intero k compreso tra 1 ed n Output: xA, k-esimo in ordine di grandezza Per semplicità supponiamo valori distinti Si può risolvere in tempo medio lineare con un algoritmo Select ottenuto modificando Randomized-Quicksort
Randomized-Select(A,p,r,k) // 1 ≤k ≤ n ifp == r returnA[p] q=Randomized-Partition(A,p,r) // A[p..q-1] <A[q] <A[q+1..r] i = q - p+1 ifk == i returnA[q] elseifk < i returnRandomized-Select(A,p,q-1,k) else returnRandomized-Select(A,q+1,r,k-i) Complessità: minima O(n), massima O(n2)
spezzando la sommatoria in corrispondenza dell’elemento medio si ottiene dove il ≤è dovuto al fatto che quando n è dispari il termine mediano viene sommato due volte.
Con la sostituzione j = n -i - 1 nella prima sommatoria si ottiene Le due sommatorie sono uguali e quindi
Usiamo il metodo di sostituzione assumendo che la soluzione sia del tipo Se esistono due costanti k1 e k2che soddisfano per ogni n>1 abbiamo trovato la soluzione.
Per n = 1 otteniamo k1 + k2=c Per n > 1 dobbiamo dimostrare che Ossia sostituendo k1n + k2 da entrambe le parti
è vera per ogni n se e ossia quando k1 ≤ 2b e k1 ≤ 2a La disequazione k1 + k2=c per il caso base fornisce infine k2 =c - k1 Dunque con k1 = min(2b,2a) ek2 =c - k1 è una soluzione e quindi