Question Comprendre le "hasard"


Je n'arrive pas à comprendre ce qui est plus aléatoire?

rand()

OU

rand() * rand()

Je trouve que c'est un vrai casse-tête, pourriez-vous m'aider?

MODIFIER:

Intuitivement, je sais que la réponse mathématique sera qu'ils sont également aléatoires, mais je ne peux m'empêcher de penser que si vous "exécutez l'algorithme des nombres aléatoires" deux fois lorsque vous multipliez les deux, vous créerez quelque chose de plus aléatoire que une fois.


822
2017-10-18 03:40


origine


Réponses:


Juste une clarification

Bien que les réponses précédentes soient exactes chaque fois que vous essayez de repérer le caractère aléatoire d'une variable pseudo-aléatoire ou sa multiplication, vous devez savoir que Au hasard() est généralement distribué uniformément, Aléatoire () * Aléatoire () n'est pas.

Exemple

C'est un échantillon de distribution aléatoire uniforme simulé à travers une variable pseudo-aléatoire:

Histogram of Random() 

        BarChart[BinCounts[RandomReal[{0, 1}, 50000], 0.01]]

Alors que c'est la distribution que vous obtenez après avoir multiplié deux variables aléatoires:

Histogram of Random() * Random() 

        BarChart[BinCounts[Table[RandomReal[{0, 1}, 50000] * 
                                 RandomReal[{0, 1}, 50000], {50000}], 0.01]]

Donc, les deux sont "aléatoires", mais leur distribution est très différente.

Un autre exemple

Tandis que 2 * Aléatoire () est uniformément distribué:

Histogram of 2 * Random()

        BarChart[BinCounts[2 * RandomReal[{0, 1}, 50000], 0.01]]

Random () + Random () ne l'est pas!

Histogram of Random() + Random()

        BarChart[BinCounts[Table[RandomReal[{0, 1}, 50000] + 
                                 RandomReal[{0, 1}, 50000], {50000}], 0.01]]

Le théorème de la limite centrale

le Théorème de la limite centrale déclare que la somme de Au hasard() tend à un distribution normale à mesure que les termes augmentent.

Avec seulement quatre termes, vous obtenez:

Histogram of Random() + Random() + Random() + Random()

BarChart[BinCounts[Table[RandomReal[{0, 1}, 50000] + RandomReal[{0, 1}, 50000] +
                   Table[RandomReal[{0, 1}, 50000] + RandomReal[{0, 1}, 50000],
                   {50000}],
         0.01]]  

Et ici vous pouvez voir la route d'un uniforme à une distribution normale en additionnant 1, 2, 4, 6, 10 et 20 variables aléatoires uniformément distribuées:

Histogram of different numbers of random variables added

modifier

Quelques crédits

Grâce à Thomas Ahle pour souligner dans les commentaires que les distributions de probabilité montrées dans les deux dernières images sont connues comme Irwin-Hall distribution 

Grâce à Heike pour elle merveilleux fonction déchirée []


1464
2017-10-18 04:03



Je suppose que les deux méthodes sont aussi aléatoires bien que mon gutfeel dirait que rand() * rand() est moins aléatoire car il multiplierait les zéros. Dès qu'un rand() est 0, le total devient 0 


151
2017-10-18 03:45



Aucun n'est plus aléatoire.

rand() génère un ensemble prévisible de nombres basé sur une graine pseudo-aléatoire (généralement basée sur l'heure actuelle, qui change constamment). La multiplication de deux nombres consécutifs dans la séquence génère une séquence de nombres différente, mais également prévisible.

S'adressant si cela va réduire les collisions, la réponse est non. Il va effectivement augmenter les collisions en raison de l'effet de multiplier deux nombres où 0 < n < 1. Le résultat sera une fraction plus petite, provoquant un biais dans le résultat vers l'extrémité inférieure du spectre.

Quelques explications supplémentaires. Dans la suite, «imprévisible» et «aléatoire» se réfèrent à la capacité de quelqu'un de deviner quel sera le prochain numéro basé sur les nombres précédents, c.-à-d. un oracle.

Donnée donnée x qui génère la liste de valeurs suivante:

0.3, 0.6, 0.2, 0.4, 0.8, 0.1, 0.7, 0.3, ...

rand() va générer la liste ci-dessus, et rand() * rand() va générer:

0.18, 0.08, 0.08, 0.21, ...

Les deux méthodes produiront toujours la même liste de nombres pour la même graine, et sont donc également prévisibles par un oracle. Mais si vous regardez les résultats pour multiplier les deux appels, vous verrez qu'ils sont tous sous 0.3malgré une distribution décente dans la séquence originale. Les chiffres sont biaisés en raison de l'effet de la multiplication de deux fractions. Le nombre résultant est toujours plus petit, donc beaucoup plus susceptible d'être une collision, tout en étant tout aussi imprévisible.


81
2017-10-20 22:43



Oversimplification pour illustrer un point. 

Supposons que votre fonction aléatoire ne produise que des sorties 0 ou 1.

random() fait partie de (0,1), mais random()*random() fait partie de (0,0,0,1) 

Vous pouvez clairement voir que les chances d'obtenir un 0 dans le second cas ne sont pas égaux à ceux d'obtenir un 1.


Quand j'ai posté cette réponse pour la première fois, je voulais la garder aussi courte que possible afin que la personne qui la lit comprenne d'un coup d'oeil la différence entre random() et random()*random(), mais je ne peux pas me retenir de répondre à la question originale ad litteram:

Lequel est le plus aléatoire?


78
2017-10-18 15:31



Voici une réponse simple. Considérez Monopoly. Vous lancez deux dés à six faces (ou 2d6 pour ceux d'entre vous qui préfèrent la notation de jeu) et prenez leur somme. Le résultat le plus commun est 7 car il y a 6 façons possibles de lancer un 7 (1,6 2,5 3,4 4,3 5,2 et 6,1). Alors que 2 ne peut être roulé que sur 1,1. Il est facile de voir que rouler 2d6 est différent de rouler 1d12, même si la plage est la même (en ignorant que vous pouvez obtenir un 1 sur un 1d12, le point reste le même). Multiplier vos résultats au lieu de les ajouter va les biaiser d'une manière similaire, avec la plupart de vos résultats à venir au milieu de la gamme. Si vous essayez de réduire les valeurs aberrantes, c'est une bonne méthode, mais cela ne va pas aider à faire une distribution égale.

(Et bizarrement, cela augmentera aussi les faibles lancements.) En supposant que votre aléatoire commence à 0, vous verrez un pic à 0 parce qu'il va tourner tout ce que l'autre rouleau est dans un 0. Considérons deux nombres aléatoires entre 0 et 1 (inclusivement Si l'un ou l'autre des résultats est un 0, l'ensemble devient un 0 quel que soit l'autre résultat La seule façon d'obtenir un 1 est que les deux soient un 1. En pratique, cela ne devrait pas poser de problème mais ça fait un graphique bizarre.)


67
2017-10-18 20:25



L'obligatoire xkcd ...
return 4; // chosen by fair dice roll, guaranteed to be random.


51
2017-10-18 04:03



Il pourrait être utile d'y penser de façon plus discrète. Pensez à vouloir générer des nombres aléatoires entre 1 et 36, donc vous décidez que la façon la plus simple est de lancer deux dés équitables à 6 faces. Vous obtenez ceci:

     1    2    3    4    5    6
  -----------------------------
1|   1    2    3    4    5    6
2|   2    4    6    8   10   12
3|   3    6    9   12   15   18
4|   4    8   12   16   20   24   
5|   5   10   15   20   25   30
6|   6   12   18   24   30   36

Nous avons donc 36 numéros, mais ils ne sont pas tous représentés équitablement, et certains ne le sont pas du tout. Les nombres proches de la diagonale centrale (coin inférieur gauche à coin supérieur droit) se produiront avec la fréquence la plus élevée.

Les mêmes principes qui décrivent la répartition injuste entre les dés s'appliquent également aux nombres à virgule flottante compris entre 0,0 et 1,0.


34
2017-10-18 03:45



Certaines choses sur le "hasard" sont contre-intuitives.

En supposant une distribution uniforme de rand(), ce qui suit vous obtiendra des distributions non-plates:

  • polarisation élevée: sqrt(rand(range^2))
  • biais culminant au milieu: (rand(range) + rand(range))/2
  • faible: biais: range - sqrt(rand(range^2))

Il existe de nombreuses autres façons de créer des courbes de biais spécifiques. J'ai fait un test rapide de rand() * rand()et il vous obtient une distribution très non linéaire.


26
2017-10-18 04:10



"random" vs "more random" est un peu comme demander quel Zero est plus nul.

Dans ce cas, rand est un PRNG, donc pas totalement aléatoire. (en fait, tout à fait prévisible si la graine est connue). Le multiplier par une autre valeur ne le rend pas plus ou moins aléatoire.

Un vrai RNG de type crypto sera réellement aléatoire. Et l'exécution de valeurs à travers toute sorte de fonction ne peut pas ajouter plus d'entropie, et peut très probablement supprimer l'entropie, ce qui ne la rend plus aléatoire.


23
2017-10-18 19:01



La plupart des implémentations de rand () ont un certain temps. C'est à dire. après un nombre énorme d'appels, la séquence se répète. La séquence des sorties de rand() * rand() répète dans la moitié du temps, de sorte qu'il est "moins aléatoire" dans ce sens.

En outre, sans une construction minutieuse, effectuer une arithmétique sur des valeurs aléatoires tend à provoquer moins de hasard. Une affiche ci-dessus citée "rand() + rand() + rand() ... "(k fois, disons) qui tendra en effet à k fois la valeur moyenne de la plage de valeurs rand() résultats. (C'est une marche aléatoire avec des étapes symétriques à ce sujet.)

Supposons pour le concret que votre fonction rand () renvoie un nombre réel aléatoire uniformément distribué dans la plage [0,1). (Oui, cet exemple permet une précision infinie Cela ne changera pas le résultat.) Vous n'avez pas choisi une langue particulière et des langages différents peuvent faire des choses différentes, mais l'analyse suivante contient des modifications pour toute implémentation non-perverse de rand ( ). Le produit rand() * rand() est également dans la plage [0,1) mais n'est plus uniformément répartie. En fait, le produit est aussi susceptible d'être dans l'intervalle [0,1 / 4) que dans l'intervalle [1 / 4,1). Plus la multiplication faussera encore plus le résultat vers zéro. Cela rend le résultat plus prévisible. En gros traits, plus prévisible == moins aléatoire.

Presque toute séquence d'opérations sur une entrée uniformément aléatoire sera aléatoire de manière non uniforme, ce qui conduira à une prévisibilité accrue. Avec prudence, on peut surmonter cette propriété, mais il aurait alors été plus facile de générer un nombre aléatoire uniformément distribué dans la plage que vous vouliez réellement plutôt que de perdre du temps avec l'arithmétique.


23
2017-10-19 12:02