559 votes

Appro. aléatoire

Est-il possible d’amorcer le générateur de nombres aléatoires (Math.random) en Javascript ?

242voto

PeterAllenWebb Points 4731

Non, il n'est pas, mais il est assez facile d'écrire votre propre générateur, ou mieux encore, utiliser une existante. Découvrez: cette question.

Aussi, voir David Bau blog pour plus d'informations sur les semis.

208voto

Antti Sykäri Points 10381

Mon autre réponse représente une approche plus traditionnelle de l'algorithme, mais j'ai trouvé Dave Scotese de commentaire pour cette réponse plus éloquent. Malheureusement, il est assez lent en raison de la manipulation de la chaîne.

Voici une version qui est environ 20 fois plus rapide et un peu plus précis.

var seed = 1;
function random() {
    var x = Math.sin(seed++) * 10000;
    return x - Math.floor(x);
}

Vous pouvez configurer seed être n'importe quel nombre, il suffit d'éviter le zéro (ou d'un multiple de Mathématiques.PI).

L'élégance de cette solution, à mon avis, vient de l'absence de toute "magie" des nombres (en plus de 10000, ce qui représente environ le montant minimum de chiffres que l'on doit jeter pour éviter des motifs étranges - voir les résultats avec les valeurs 10, 100, 1000). La brièveté est également agréable.

C'est un peu plus lent que les Mathématiques.random() (par un facteur de 2 ou 3), mais je crois que c'est à peu près aussi rapide que tout autre solution écrite en JavaScript.

51voto

Antti Sykäri Points 10381

Non, mais ici est un simple générateur pseudo, j'ai adapté de Wikipedia:

var m_w = 123456789;
var m_z = 987654321;
var mask = 0xffffffff;

// Takes any integer
function seed(i) {
    m_w = i;
}

// Returns number between 0 (inclusive) and 1.0 (exclusive),
// just like Math.random().
function random()
{
    m_z = (36969 * (m_z & 65535) + (m_z >> 16)) & mask;
    m_w = (18000 * (m_w & 65535) + (m_w >> 16)) & mask;
    var result = ((m_z << 16) + m_w) & mask;
    result /= 4294967296;
    return result + 0.5;
}

33voto

Antti Sykäri de l'algorithme est belle et courte. J'ai d'abord fait une variation, qui a remplacé Javascript Math.aléatoire lorsque vous appelez les Mathématiques.graine(s), mais Jason a commenté que le retour de la fonction serait mieux:

Math.seed = function(s) {
    return function() {
        s = Math.sin(s) * 10000; return s - Math.floor(s);
    };
};

// usage:
var random1 = Math.seed(42);
var random2 = Math.seed(random1());
Math.random = Math.seed(random2());

Cela vous donne une autre fonctionnalité que Javascript n'est pas: indépendantes multiples générateurs aléatoires. C'est particulièrement important si vous voulez avoir de multiples reproductible des simulations en cours d'exécution au même moment.

-1voto

Simo Endre Points 2569

Voici une bien jolie graines générateur de nombre. Il renvoie des nombres à virgule flottante entre -1.0 et 1.0.

function seed(x) {
    x = (x<<13) ^ x;
    return ( 1.0 - ( (x * (x * x * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0);
}  

Dans l'exemple nous remplir un tableau avec des nombres aléatoires entre 0 et 256

var p = [];

for (var i = 0; i < 256; i++) {
    p[i] = Math.floor(~~seed(i) * 256);
}

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