11 votes

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

Javascript Math.random() renvoie un nombre psuedo-aléatoire avec une distribution "uniforme".

J'ai besoin de générer un nombre aléatoire dans l'intervalle [0,1] qui est incliné d'un côté ou de l'autre. (C'est-à-dire qu'il y a plus de chances d'obtenir des nombres proches de 0 ou proches de 1).

Idéalement, j'aimerais disposer d'un paramètre pour définir cette courbe.

Je suppose que je peux faire Math.random^2 pour obtenir un tel résultat, mais quels sont les moyens plus sophistiqués d'y parvenir ?

17voto

Nishanth Points 3254

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 en utilisant la distribution cumulative inverse.

unif = Math.random()

Je ne suis pas familier avec javascript mais cela devrait être clair :

beta = sin(unif*pi/2)^2

PS : vous pouvez générer de nombreux nombres de ce type et tracer un histogramme. enter image description here

Edit :

Pour une inclinaison vers 0, transformer le beta comme -

beta_left = (beta < 0.5) ? 2*beta : 2*(1-beta);

enter image description here

Pour une inclinaison vers 1, transformer en -

beta_right = (beta > 0.5) ? 2*beta-1 : 2*(1-beta)-1;

enter image description here

4voto

tremby Points 482

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

Cette méthode utilise deux des nombres aléatoires réguliers de Javascript. Le premier est multiplié par lui-même (plus l'exposant est grand, plus l'effet d'inclinaison est important), et le second choisit le côté de la distribution à incliner.

function skewedRandom() {
    const a = Math.pow(Math.random(), 2);
    if (Math.random() < 0.5) {
        return a;
    }
    return 1 - a;
}

Dans ce code, l'exposant est fixé à 2. Un exemple d'histogramme provenant de 10 000 exécutions avec l'exposant à 2 comme ci-dessus :

Histogram with exponent 2

Avec l'exposant 3 :

Histogram with exponent 3

Et avec l'exposant 10 : Histogram with exponent 10

2voto

Xotic750 Points 6649

Vous pouvez utiliser window.crypto.getRandomValues si disponible

<div id="result"></div>

var randVal = new Uint8Array(1);

window.crypto.getRandomValues(randVal);

document.getElementById("result").textContent = randVal[0] / 255;

Sur jsfiddle

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

Ou peut-être comme ceci

<div id="result"></div>

function poissonRandomNumber(lambda) {
    var L = Math.exp(-lambda),
        k = 0,
        p = 1;

    do {
        k = k + 1;
        p = p * Math.random();
    } while (p > L);

    return k - 1;
}

document.getElementById("result").textContent = poissonRandomNumber(100);

également sur jsfiddle

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X