168 votos

Semillas al azar JavaScript

¿Es posible sembrar el generador de números aleatorios (Math.random) en Javascript?

92voto

PeterAllenWebb Puntos 4731

No, no es, pero es bastante fácil escribir un generador propio, o mejor aún utilizar uno ya existente. Echale un vistazo: esta pregunta relacionada.

Además, ver el blog de David Bau para más información sobre la siembra.

61voto

Antti Sykäri Puntos 10381

Mi otra respuesta representa más tradicional de algoritmo, pero me he encontrado con Dave Scotese del comentario a esta respuesta , para ser más elocuente. Por desgracia, es bastante lento debido a la manipulación de cadenas.

He aquí una versión que es aproximadamente 20 veces más rápido y un poco más preciso así.

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

Usted puede configurar seed a ser cualquier número, sólo evitar cero (o cualquier múltiplo de Math.PI).

La elegancia de esta solución, en mi opinión, viene de la falta de la "magia" de los números (además de 10000, lo que representa cerca de la mínima cantidad de dígitos debe tirar para evitar patrones impares - vea los resultados con valores de 10, 100, 1000). La brevedad es también agradable.

Es un poco más lento que Math.random() (por un factor de 2 o 3), pero creo que es tan rápida como la de cualquier otra solución escrita en JavaScript.

16voto

Algoritmo de Antti Sykäri es bonito y breve. Inicialmente hice una variación que reemplazó Math.random de Javascript cuando se llama a Math.seed(s), pero entonces Jason comentó que sería mejor volver a la función:

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());

Esto le da otra funcionalidad que no tiene Javascript: varios generadores aleatorios independientes. Eso es especialmente importante si usted quiere tener múltiples simulaciones repetibles corriendo al mismo tiempo.

13voto

Antti Sykäri Puntos 10381

No, pero esto es un simple generador pseudoaleatorio 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;
}

-1voto

Simo Endre Puntos 2569

Aquí es un buen generador de números sembrado. Devuelve números de coma flotante entre -1,0 y 1,0.

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

En ejemplo podemos rellenar un array con números aleatorios entre 0 y 256

var p = [];

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

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X