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 powe 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))