Supponiamo di ordinare N dati col seguente algoritmo:
trovare il minimo tra i dati;
questo è il 1° dato;
trovare il minimo tra i rimanenti; questo è il 2° dato; e così via.
(1) prova a stimare in base a un ragionamento teorico come, al crescere della quantità N dei dati, cresce il tempo di ordinamento t(N),
ossia di valutare l'ordine di infinito di t(N) rispetto a N.
(2) controlla questa stima con uno studio sperimentale mediante un linguaggio di programmazione.
(1)
Il tempo per ordinare i dati dipende dal numero di confronti tra coppie di numeri che si devono eseguire.
I confronti da eseguire per trovare il minimo tra N dati sono N-1. Quelli per ordinare N-1 dati sono N-2.
In tutto sono da eseguire 1+2+
+(N-1) confronti.
1+2+
+(N-1) = (1+N-1)(N-1)/2 = N(N-1)/2 = N2/2-N/2.
Il tempo dovrebbe, quindi, crescere con lo stesso ordine di N2.
(2) Si può stimare il tempo con dei semplici script online. Vedi qui (guarda il terzo esempio):
If I had: 1000 numbers, 89 ms; 2000 numbers, 313 ms; 4000 numbers, 1223 ms; 8000 numbers, 4898 ms.
313 / 89 = 3.52, 1223 / 313 = 3.91, 4898 / 1223 = 4.00. Doubling N the time approximately fourfold.
I can deduce that
Concludendo, al raddoppiare di N t(N) tende a moltiplicarsi per 4 = 22. Posso supporre che che t(N) sia dello stesso ordine di N2.
Per approfondimenti:
infiniti e infinitesimi neGli Oggetti Matematici.
Ecco un possibile programma in R, e alcune possibili uscite (per l'uso di <<- vedi qui):
x <- NULL; x <- runif(1e4) # Ho messo in x molti dati casuali (10 mila) ord <- function(n) {y <<- NULL; for(i in 1:n) { posto <- i; for(h in i:n) if( x[h] < x[posto] ) posto <- h; k <- x[i]; y[i] <<- x[posto]; x[i] <- x[posto];x[posto] <- k} } # ord è un algoritmo che mette in ordine in y i primi n dati messi in x # Vediamo ad esempio che cosa accade per 6 dati ord(6); x[1:6]; y[1:6] # 0.4160138 0.6842613 0.6266933 0.6351947 0.2096925 0.6838983 # 0.2096925 0.4160138 0.6266933 0.6351947 0.6838983 0.6842613 # Vediamo che cosa accade per 100 dati e, via via, raddoppiandone la quanità: s0 <- 1 s <- proc.time()[3]; ord(100); s <- proc.time()[3]-s; s; s/s0; s0 <- s # 0.05 0.05 s <- proc.time()[3]; ord(200); s <- proc.time()[3]-s; s; s/s0; s0 <- s # 0.09 1.8 s <- proc.time()[3]; ord(400); s <- proc.time()[3]-s; s; s/s0; s0 <- s # 0.38 4.222222 s <- proc.time()[3]; ord(800); s <- proc.time()[3]-s; s; s/s0; s0 <- s # 1.42 3.736842 s <- proc.time()[3]; ord(1600); s <- proc.time()[3]-s; s; s/s0; s0 <- s # 5.58 3.929577 s <- proc.time()[3]; ord(3200); s <- proc.time()[3]-s; s; s/s0; s0 <- s # 22.42 4.017921
Disponendo del concetto di derivata, si può effettuare lo studio sperimentale
anche in un altro modo: studiare come varia
s0 <- 0 s <- proc.time()[3]; ord(500); s <- proc.time()[3]-s; s-s0; s0 <- s # 0.57 s <- proc.time()[3]; ord(1000); s <- proc.time()[3]-s; s-s0; s0 <- s # 1.65 s <- proc.time()[3]; ord(1500); s <- proc.time()[3]-s; s-s0; s0 <- s # 2.69 s <- proc.time()[3]; ord(2000); s <- proc.time()[3]-s; s-s0; s0 <- s # 3.82 s <- proc.time()[3]; ord(2500); s <- proc.time()[3]-s; s-s0; s0 <- s # 4.7 s <- proc.time()[3]; ord(3000); s <- proc.time()[3]-s; s-s0; s0 <- s # 6.01 1.65-0.57; 2.69-1.65; 3.82-2.69; 4.7-3.82; 6.01-4.7 # 1.08 1.04 1.13 0.88 1.31Si vede che le variazioni di t(N) crescono, e che le variazioni delle variazioni (variazioni seconde) oscillano attorno a un valore positivo. Questo fa supporre che t(n) abbia l'ordine di N2 (che ha derivata seconda costante).