Disons que je veux générer un ensemble de nombres aléatoires à partir de l'intervalle (a, b)
. La séquence générée doit également avoir la propriété d'être triée. Je peux penser à deux façons d'y parvenir.
Soit n
la longueur de la séquence à générer.
1er algorithme:
Let `offset = floor((b - a) / n)`
for i = 1 up to n:
generate a random number r_i from (a, a+offset)
a = a + offset
add r_i to the sequence r
2ème algorithme:
for i = 1 up to n:
generate a random number s_i from (a, b)
add s_i to the sequence s
sort(r)
Ma question est la suivante: l'algorithme 1 produit-il des séquences aussi bonnes que celles générées par l'algorithme 2?
random-generation
ultrajohn
la source
la source
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))
Réponses:
Le premier algorithme échoue gravement pour deux raisons:
Prendre la parole de peut le réduire considérablement. En effet, quand , il sera nul, vous donnant un ensemble dont les valeurs sont toutes les mêmes!b - a < n( a - b ) / n b - a < n
Lorsque vous ne prenez pas la parole, les valeurs résultantes sont trop uniformément réparties. Par exemple, dans tout échantillon aléatoire simple de iid variables uniformes (disons entre et ), il y a chance que le le plus grand ne sera pas dans l'intervalle supérieur de à . Avec l'algorithme 1, il y a chances que le maximum soit dans cet intervalle. À certaines fins, cette super-uniformité est bonne, mais en général, c'est une erreur terrible car (a) de nombreuses statistiques seront ruinées mais (b) il peut être très difficile de déterminer pourquoi.a = 0 b = 1 ( 1 - 1 / n ) n ≈ 1 / e ≈ 37 % 1 - 1 / n 1 100 %n a = 0 b = 1 ( 1 - 1 / n )n≈ 1 / e ≈ 37 % 1 - 1 / n 1 100 %
Si vous voulez éviter le tri, générez plutôt variables indépendantes exponentiellement distribuées. Normaliser leur somme cumulée à la plage en divisant par la somme. Supprimez la plus grande valeur (qui sera toujours ). Redimensionner à la plage .( 0 , 1 ) 1 ( a , b )n + 1 ( 0 , 1 ) 1 ( a , b )
Les histogrammes des trois algorithmes sont affichés. (Chacun représente les résultats cumulatifs de ensembles indépendants de valeurs chacun.) L'absence de toute variation visible dans l'histogramme de l'algorithme 1 montre le problème là-bas. La variation dans les deux autres algorithmes est exactement ce à quoi s'attendre - et ce dont vous avez besoin d'un générateur de nombres aléatoires.n = 1001000 n = 100
Pour de nombreuses autres façons (amusantes) de simuler des variations uniformes indépendantes, voir Simulation de tirages à partir d'une distribution uniforme à l'aide de tirages à partir d'une distribution normale .
Voici le
R
code qui a produit la figure.la source
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.
Ce qui donne l'algorithme suivant:
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
la source
Cela dépend également de ce que vous faites avec les nombres aléatoires. Pour les problèmes d'intégration numérique, la première méthode (lorsqu'elle est corrigée en supprimant l'opérateur de plancher) produira un ensemble de points supérieur. Ce que vous faites est une forme d’échantillonnage stratifié et il a l’avantage d’éviter l’agglutination. il est impossible d'obtenir toutes vos valeurs dans la plage 0- (ba) / n par exemple. Cela dit, pour d'autres applications, cela pourrait être très mauvais, cela dépend de ce que vous voulez en faire.
la source