Il primo algoritmo produce numeri troppo uniformemente distanziati
Vedi anche serie a bassa discrepanza .
Supponendo di volere 2 numeri casuali in . Con dati uniformi reali, la probabilità è 50:50 che siano entrambi più grandi o più piccoli di 0,5 contemporaneamente. Con il tuo approccio, la possibilità è 0. Quindi i tuoi dati non sono uniformi.[0;1]
(Come sottolineato, questo può essere un esempio proprietà desiderata per la stratificazione. Serie a bassa discrepanza come Halton e Sobel non hanno i loro casi d'uso.)
Un approccio corretto ma costoso (per valori reali)
... è usare numeri casuali distribuiti in beta. La statistica dell'ordine di rango della distribuzione uniforme è distribuita in beta. Puoi usarlo per disegnare casualmente il più piccolo , quindi il secondo più piccolo, ... ripeti.
Supponendo che i dati debbano essere generati in . Il valore più piccolo è distribuito. (Per i casi successivi, ridurre e riscalare all'intervallo rimanente). Per generare un casuale beta generale, dovremmo generare due valori casuali distribuiti Gamma. Ma . Quindi . Possiamo campionare numeri casuali da questa distribuzione come per questo.[0;1]Beta[1,n]n1−X∼Beta[n,1]−ln(1−X)∼Exponential[n]−ln(U[0;1])n
−ln(1−x)1−xx=−ln(1−u)n=u1n=1−u1n
Che produce il seguente algoritmo:
x = a
for i in range(n, 0, -1):
x += (b-x) * (1 - pow(rand(), 1. / i))
result.append(x)
Potrebbero esserci delle instabilità numeriche, e il calcolo pow
e una divisione per ogni oggetto potrebbero risultare più lenti dell'ordinamento.
Per i valori interi potrebbe essere necessario utilizzare una distribuzione diversa.
L'ordinamento è incredibilmente economico, quindi basta usarlo
Ma non preoccuparti. L'ordinamento è così ridicolmente economico, quindi basta ordinare. Nel corso degli anni, abbiamo capito bene come implementare algoritmi di ordinamento che l'ordinamento raddoppia non vale la pena evitare. Teoricamente è ma il termine costante è così ridicolmente piccolo in una buona implementazione che questo è l'esempio perfetto di come possano essere inutili risultati di complessità teorica . Esegui un benchmark. Genera 1 milione di random con e senza ordinamento. Eseguilo un paio di volte e non sarei sorpreso se abbastanza spesso l'ordinamento batte il non ordinamento, perché il costo dell'ordinamento sarà comunque molto inferiore all'errore di misurazione.O(nlogn)
R
. Al fine di generare un array di insiemi di numeri casuali in un intervallo uniforme , il seguente codice funziona: .rand_array <- replicate(k, sort(runif(n, a, b))