Лучшая случайная функция в JavaScript

Я cuApplyRandom: function () {var $ this = Evolution; var total = $ this.Settings.grid_x * $ this.Settings.grid_y; var range = parseInt (всего * ($ this.Settings.randomPercentage / 100)); for (var i = 0; i <total; i ++) {$ this.Infos.grid [i] = false; } for (var i = 0; i <range; i ++) {var random = Math.floor ((Math.random () * total) + 1); $ this.Infos.grid [random] = true; } $ this.PrintGrid (); }, в результате чего воспроизведение JavaScript Conway's Game of Life в JavaScript и я заметил, что функция var position = (y * 10) + x; всегда возвращает определенный шаблон. Вот пример рандомизированного результата в позиции var = (y * $ this.Settings.grid_x) + x; Сетка 0x100:

введите описание изображения здесь

Кто-нибудь знает, как получить рандомизированные цифры?

10

[ОБНОВИТЬ]

Я создал jsFiddle здесь: http://jsfiddle.net/5Xrs7/1/

[ОБНОВИТЬ]

Кажется, что ApplyRandom () был в порядке после всех (спасибо raina77ow). Извините, народ! :(. Если вас интересует результат, вот обновленная версия игры: http://jsfiddle.net/sAKFQ/

(Но я думаю, что осталось несколько ошибок ...)

javascript,math,random,

18

Ответов: 6


11 принят

Эта строка в вашем коде ...

var bias = $this.Settings.randomPercentage / 100;
for (var i = 0; i < total; i++) {
  $this.Infos.grid[i] = Math.random() < bias;
}

... это то, что вызывает эту «неслучайность». Это действительно должно быть ...

var random = Math.floor((Math.random() * total) + 1);

Я предполагаю, что это 10был оригинальный размер этой сетки, вот почему он здесь. Но это явно неправильно: вы должны выбрать свою позицию на основе текущего размера сетки.


В качестве опоры, без обид, но я все же считаю, что алгоритм, указанный в ответе @JayC, превосходит ваш. И это довольно просто реализовать, просто смените две петли в Math.random=(function(rand) { var salt=0; document.addEventListener('mousemove',function(event) { salt=event.pageX*event.pageY; }); return function() { return (rand()+(1/(1+salt)))%1; }; })(Math.random); функции на одну:

r

С этим изменением вы больше не будете страдать от побочного эффекта повторного использования одинаковых номеров в r < 0.2строке, что снизило фактическую заполняемость ячейки в исходном коде.


3

Math.random - это псевдослучайный метод, поэтому вы получаете эти результаты. A by pass часто используется для того, чтобы поймать позицию курсора мыши, чтобы добавить соль к результатам Math.random:

Math.random()

Это не совсем случайно, но немного больше;)


2

Лучшее решение, вероятно, заключается не в случайном выборе очков и их окраске в черный цвет, а в том, чтобы пройти через каждую точку, решить, какие шансы они должны быть заполнены, а затем заполнить соответственно. (То есть, если вы хотите, чтобы в среднем% 20 процентов вероятность его заполнения, сгенерируйте свое случайное число rи заполните, когда Math.random я увидел симулятор Life в WebGL, и это то, что он делает для инициализации ... IIRC.

Изменить: Вот еще одна причина, чтобы рассмотреть альтернативные методы живописи. В то время как случайный выбор пикселей может закончиться меньшим количеством работы и меньшим вызовом вашего генератора случайных чисел, что может быть хорошо , в зависимости от того, что вы хотите. Как бы то ни было, вы, похоже, выбрали способ, в котором будет заполнен не более процентов ваших пикселей. ЕСЛИ вы следили за заполняемыми пикселями и выбрали заполнение другого пикселя, если он уже был заполнен, по сути, все ваши действия перетасовывают точный процент черных пикселей среди ваших белых пикселей. Сделайте это по-своему, и процент выбранных пикселей будет соответствовать биномиальному распределению. Иногда процент заполняется будет немного больше, иногда немного меньше. Набор всех перетасовки является строгим подмножеством возможностей, порождающих подобный выбор (который, строго говоря, содержит все возможности для рисования доски, просто с астрономически низким шансом получить большинство из них). Проще говоря, случайный выбор для каждого пикселя позволит увеличить дисперсию.

Опять же , я мог бы изменить алгоритм перетасовки, чтобы выбрать процент пикселей на основе чисел, генерируемых функцией биномиального распределения вероятности, с определенным ожидаемым / средним значением вместо самого ожидаемого / среднего значения, и я честно не знаю, что это 'd быть любым другим - по крайней мере теоретически - чем использовать коэффициенты для каждого пикселя с ожидаемым / средним значением. Там многое можно сделать.


0

Можешь попробовать

Для обсуждения силы Math.random(), см. Этот вопрос .


0

Реализация, Math.randomвероятно, основана на линейном конгруэнтном генераторе , одна слабость которой заключается в том, что случайное число зависит от более раннего значения, создавая такие предсказуемые шаблоны, как это, в зависимости от выбора констант в алгоритме. Известный пример эффекта плохого выбора констант можно увидеть в RANDU .

Вихрь Мерсенна генератор случайных чисел не имеет этого недостатка. Вы можете найти реализацию MT в JavaScript, например, здесь: https://gist.github.com/banksean/300494


Обновление. Увидев ваш код, у вас есть проблема в коде, который отображает сетку. Эта строка:

var position = (y * 10) + x;

Должно быть:

var position = (y * grid_x) + x;

С этим исправлением нет заметной картины.

JavaScript, математика, случайный,
Похожие вопросы