Seedable генератор случайных чисел JavaScript

134
задан Ilmari Karonen 10 March 2014 в 21:46
поделиться

4 ответа

Один из вариантов - http://davidbau.com/seedrandom , который представляет собой замещающую замену Math.random () на основе RC4 с хорошими свойствами.

113
ответ дан 23 November 2019 в 23:56
поделиться

если Вам не нужна возможность отбора, просто используйте Math.random() и создайте функции помощника вокруг этого (например, randRange(start, end)).

я не уверен, какой RNG Вы используете, но лучше знать и документировать его так, Вы знаете, это - характеристики и ограничения.

Как сказанный Starkii, вихрь Мерсенна является хорошим PRNG, но не легко реализовать. Если Вы хотите сделать это, сами пытаются реализовать LCG - это очень легко, имеет достойные качества случайности (не столь хороший как вихрь Мерсенна), и можно использовать некоторые популярные константы.

function RNG(seed) {
  // LCG using GCC's constants
  this.m = 0x80000000; // 2**31;
  this.a = 1103515245;
  this.c = 12345;

  this.state = seed ? seed : Math.floor(Math.random() * (this.m - 1));
}
RNG.prototype.nextInt = function() {
  this.state = (this.a * this.state + this.c) % this.m;
  return this.state;
}
RNG.prototype.nextFloat = function() {
  // returns in range [0,1]
  return this.nextInt() / (this.m - 1);
}
RNG.prototype.nextRange = function(start, end) {
  // returns in range [start, end): including start, excluding end
  // can't modulu nextInt because of weak randomness in lower bits
  var rangeSize = end - start;
  var randomUnder1 = this.nextInt() / this.m;
  return start + Math.floor(randomUnder1 * rangeSize);
}
RNG.prototype.choice = function(array) {
  return array[this.nextRange(0, array.length)];
}

var rng = new RNG(20);
for (var i = 0; i < 10; i++)
  console.log(rng.nextRange(10, 50));

var digits = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];
for (var i = 0; i < 10; i++)
  console.log(rng.choice(digits));
24
ответ дан 23 November 2019 в 23:56
поделиться

Если Вы хотите смочь указать семя, просто необходимо заменить вызовы к getSeconds() и getMinutes(). Вы могли передать в интервале и использовать половину из нее модификация 60 для значения секунд и другой половины 60 по модулю, чтобы дать Вам другую часть.

Однако этот метод похож на мусор. Выполнение надлежащей генерации случайных чисел очень трудно. Очевидная проблема с этим состоит в том, что семя случайного числа основано на секундах и минутах. Предположить семя и воссоздать Ваш поток случайных чисел только требуют попытки 3 600 других секунд и мелких комбинаций. Это также означает, что существует только 3 600 различных возможных семян. Это корректируемо, но я с подозрением относился бы к этому RNG от запуска.

, Если Вы хотите использовать лучший RNG, попробуйте вихрь Мерсенна . Это - хорошо протестированный и довольно устойчивый RNG с огромной орбитой и превосходной производительностью.

РЕДАКТИРОВАНИЕ: Я действительно должен быть корректным и назвать это Генератором псевдослучайных чисел или PRNG.

"Любой, кто использует арифметические методы для создания случайных чисел, в состоянии греха".
                                                                                                                                                                                                                                                                                                                   ---John von Neumann

22
ответ дан 23 November 2019 в 23:56
поделиться

Код, который Вы перечислили отчасти, похож Lehmer RNG. Если это верно, затем 2147483647 самое большое 32-разрядное целое число со знаком, 2147483647 самое большое 32-разрядное начало, и 48271 множитель полного периода, который используется для генерации чисел.

, Если это верно, Вы могли бы изменить RandomNumberGenerator, чтобы взять в дополнительном параметре seed и затем установить this.seed на seed; но необходимо было бы стараться удостовериться, что семя привело бы к хорошему распределению случайных чисел (Lehmer может быть странным как этот) - но большинство семян будет прекрасно.

8
ответ дан 23 November 2019 в 23:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: