Le premier algorithme produit des nombres trop espacés
Voir également les séries à faible écart .
En supposant que vous vouliez 2 nombres aléatoires dans . Avec de vraies données uniformes, la probabilité est de 50:50, elles sont à la fois supérieures ou inférieures à 0,5 en même temps. Avec votre approche, la chance est 0. Vos données ne sont donc pas uniformes.[ 0 ; 1 ]
(Comme l' a souligné, cela peut être une propriété souhaitée , par exemple pour la stratification. Série à faible discrépance comme Halton et Sobel n'ont leurs cas d'utilisation.)
Une approche appropriée mais coûteuse (pour les valeurs réelles)
... consiste à utiliser des nombres aléatoires distribués bêta. La statistique d'ordre de rang de la distribution uniforme est distribuée bêta. Vous pouvez l'utiliser pour dessiner au hasard le plus petit , puis le deuxième plus petit, ... répétez.
[ 0 ; 1 ]Bêta [ 1 , n ]n1 - X∼ Bêta [ n , 1 ]- ln( 1 - X) ∼ Exponentielle [ n ]- ln( U[ 0 ; 1 ] )n
- ln( 1 - x )1 - xX= - ln( 1 - u )n= u1n= 1 - u1n
Ce qui donne l'algorithme suivant:
x = a
for i in range(n, 0, -1):
x += (b-x) * (1 - pow(rand(), 1. / i))
result.append(x)
Il peut y avoir des instabilités numériques impliquées, et le calcul pow
et une division pour chaque objet peuvent s'avérer plus lents que le tri.
Pour les valeurs entières, vous devrez peut-être utiliser une distribution différente.
Le tri est incroyablement bon marché, alors utilisez-le
O ( n logn )
R
. Afin de générer une matrice de ensembles de nombres aléatoires dans un intervalle uniforme , le code suivant fonctionne: . n [ a , b ]rand_array <- replicate(k, sort(runif(n, a, b))