11
votes

Générer un nombre aléatoire avec une distribution non uniforme

math.random () renvoie un numéro pseudo-aléatoire avec une distribution "uniforme".

J'ai besoin de générer un nombre aléatoire dans la plage [0,1] qui est asymétrique de chaque côté. (Sens, plus de chances d'obtenir plus de numéros à côté de 0 ou à côté de 1)

Idéalement, je voudrais avoir un paramètre pour définir cette courbe.

J'ai supposé que je puisse faire math.random ^ 2 pour obtenir un tel résultat, mais quelles manières plus sophistiquées sont là pour y parvenir?


3 commentaires

Par réponse ci-dessous, les distributions de Poisson ne sont pas [0,1]. Ils sont [0, infini). Alors, que veux-tu?


+1, c'est une bonne question avec une solution non triviale.


@djechlin Techniquement les variables aléatoires de Poisson ont un support sur {0, ..., ∞}, cette question de penser à prendre des échantillons de processus de Poisson sur les espaces générant une variable aléatoire de poisson basée sur la distribution de taux sous-jacente sur l'espace [0, ∞) que est généralement considéré dans les processus de Poisson. Si vous envisagez l'intégralité de cet espace, vous obtenez un nombre variable aléatoire de poisson avec une moyenne ∞, ce qui est traditionnellement considéré comme un cas de bord valide dans lequel vous vous attendez à la variable aléatoire de Poisson = ∞ (W.P. = 1).


4 Réponses :


3
votes

Je pense que vous devez repenser votre question. Le Poisson est une distribution de comptage spécifiée en termes de taux, comme le nombre d'occurrences de quelque chose que je vois en moyenne par période. Il donne des entiers positifs afin que le résultat ne peut pas être juste dans la plage [0,1]. Pouvez-vous s'il vous plaît clarifier ce que vous voulez?

Peu importe, pour générer un poisson avec un taux de poisson Lambda Un algorithme est le suivant: xxx

où "rand" est l'appel à un uniforme (0,1). Je ne connais pas JavaScript, mais cela devrait être assez simple pour que vous puissiez mettre en œuvre.

Répondre à la question modifiée:

Il y a plusieurs distributions qui génèrent Résultats sur une gamme délimitée, mais beaucoup d'entre eux ne sont pas pour les faibles de cœur, tels que la famille Johnson ou la distribution bêta.

Une distribution de triangle serait facile. SQRT (RAND) donnera une distribution de triangle en direction de 1, tandis que (1-sqrt (1-rand)) donnera une distribution triangulaire à une gêne à zéro.

Un triangle plus général avec le mode (le plus fréquent valeur) à m (où 0 <= m <= 1) peut être généré avec xxx

note que chaque appel de Rand est un nombre aléatoire uniforme séparé, cela ne va pas Soyez correct si vous générez une valeur pour RAND et utilisez-le tout au long.


1 commentaires

Vous avez absolument raison. Je pensais à penser à tout ça en arrière :) Merci de me donner droit (et dans la bonne direction!). En tout cas, bon de savoir concernant l'algorithme



2
votes

YOY peut utiliser window.crypto.getrandomvalues ​​ Si disponible xxx

sur jsfiddle

(Si c'est ce que vous demandez, je ne suis pas sûr)

ou peut-être comme ce xxx

aussi sur jsfiddle


1 commentaires

Crypto.GetRandomValues ​​() est bon pour le moment où vous avez besoin de chiffres prêts à la preuve ou à une sécurité cryptographique. math.random () est bien partout ailleurs, et c'est mieux lorsque la vitesse est nécessaire, par exemple avec des jeux (mais pas pour l'authentification).



16
votes

Je pense que vous voulez Distribution bêta avec alpha = beta = 0.5

Il est possible de transformer un nombre aléatoire uniforme en distribution bêta à l'aide de la distribution cumulative inverse. xxx

Je ne suis pas familier avec JavaScript , mais cela devrait être clair: xxx

ps: vous pouvez générer de nombreux numéros et histogramme de tracé Entrez la description de l'image ici

EDIT:

Pour biaiser vers 0, transformez les valeurs bêta as - xxx

 Entrez la description de l'image ici

pour asymétrie vers 1, transformer comme - xxx

Entrez la description de l'image ici


3 commentaires

Intéressant! Je vais essayer cela. Merci pour l'illustration graphique. Que ferais-je si je souhaite que la répartition ne soit pas unique à un côté?


Eh bien, il existe des moyens de cartographier la distribution uniforme à toute distribution à l'aide de la méthode de CDF inverse. Je mettrai mis à jour ma réponse pour transformer les numéros déjà en rakew droit / gauche.


C'est exactement ce dont j'avais besoin! Merci un tas



3
votes

Je viens de trouver un moyen plus simple d'obtenir des chiffres aléatoires à chaque côté et qui n'a pas de dépendances.

Cette méthode utilise deux des numéros aléatoires habituels de JavaScript. Le premier est multiplié avec lui-même (plus l'exposant plus grand, plus l'effet d'inclinaison) et le second choisit de quel côté de la distribution à incliner. xxx

dans ce code L'exposant est défini sur 2. Un exemple d'histogramme de 10 000 exécutions avec l'exposant à 2 comme ci-dessus:

histogramme avec exponent 2

avec exponent 3 :

 histogramme avec exponent 3

et avec l'exposant 10: Histogramme avec exponent 10


1 commentaires

Je note un problème possible avec cette méthode. Math.Random () produit des chiffres de 0 inclus à 1 exclusivité. Cette méthode peut toutefois produire des nombres de 0 à 1 inclusivement. Si c'est un problème pour vous, un correctif possible pourrait être de modifier la dernière ligne vers Retour 1 - Number.epsilon - A; . Bien que je ne sois pas sûr si cela pourrait jamais produire une valeur légèrement inférieure à 0.