Почему эти случайные числа медленно тяготеют к отрицательному значению?

Программа должна делать следующее:

  1. Инициализирует сетку значений «ActualGridValues» (X строк на Y столбцов), равную 0.
  2. Создает другую сетку значений, «RandomGridValues» (X строк на Y столбцов), определяет каждую ячейку в сетке как равную среднему значению N случайных чисел в диапазоне от -Z до Z.
  3. Добавляет число из RandomGridValues ​​в соответствующую ячейку из ActualGridValues.
  4. Для каждой ячейки в ActualGridValues ​​он также добавляет значения соседних ячеек.
  5. Повторяет шаги 2–4 до бесконечности.

В результате случайные структуры сливаются в сетке. Группы с высокими положительными значениями будут влиять на соседние ячейки и вызывать их высокий перекос, а группировки низких отрицательных значений будут делать то же самое, но с перекосом в меньшую сторону.

Суммарный продукт всех значений во всех ячейках ДОЛЖЕН быть равен нулю. Хотя существуют локализованные группы чисел с высоким и низким перекосом, при достаточно большом размере выборки сумма всех ячеек должна быть равна нулю.

Проблема в том, что после, скажем, 1000 итераций значения последовательно отклоняются в отрицательную сторону. У вас есть структуры и локализованные максимумы и минимумы, но общие значения всегда имеют отрицательный перекос. (Это означает, что со временем вся сетка заполняется только отрицательными числами).

Каждый раз при запуске моделирования значения искажаются отрицательно. Есть мысли о том, почему?

Изменить: я ограничил проблему следующей функцией. Среднее значение всех чисел в RandomGridValue почти всегда оказывается отрицательным.

//For every cell value, this function generates a string of random numbers between -RandMax/2 and +RandMax/2. It then takes the average of all of these numbers. It assigns that value to a cell in the RandomGridValue array. 

function AddChaos() {
     for (var l = 0; l < GridX; l++) {
         for (var m = 0; m < GridY; m++) {
             var RandomGrid = 0;
             for (var n = 0; n < RandNums; n++) {
                 RandomGrid = RandomGrid + Math.random() * RandMax * 2 - RandMax;
             }
             RandomGridValue[l][m] = RandomGrid / RandNums;
         }
     }
 }  

person user2161457    schedule 12.03.2013    source источник
comment
Мне этот вопрос показался интересным, поэтому я провел беглый поиск и нашел следующее: stackoverflow.com/ вопросы / 3956478 / понимание-случайность. Похоже, что умножение случайных чисел может привести к искажению результатов. Думаю, стоит посмотреть. Этот пост касается умножения двух случайных чисел, хотя в вашем коде похоже, что вы просто масштабируете его, поэтому я не уверен, будет ли это такой же эффект. Вот еще одно сообщение: stackoverflow.com/questions/11383242/.   -  person Aaron Blenkush    schedule 12.03.2013
comment
Именно этот перекос и пытается зафиксировать эта программа. Однако это должно смещать распределение в сторону обеих конечных точек, а не одной конкретной конечной точки.   -  person user2161457    schedule 12.03.2013
comment
Если вы хотите суммировать # RandNums случайных значений в [-RandMax, RandMax], вам нужно сделать это RandomGrid += (Math.random()*RandMax - 2*RandMax); - иначе вы получите либо все положительные, либо все отрицательные значения в зависимости от знака RandMax   -  person Cris Stringfellow    schedule 12.03.2013
comment
@ user2161457 Я думал, вы пытаетесь убрать перекос результатов. Я предоставил эти ссылки, чтобы вы могли видеть, что вызывает перекос, чтобы вы могли его избежать.   -  person Aaron Blenkush    schedule 12.03.2013
comment
@AaronBlenkush Ну, я пытаюсь избежать однонаправленного перекоса в сторону одного знака. Что должно произойти, так это двунаправленный перекос, где 50% значений равны RandMax / 2, а 50% значений - -RandMax / 2, а среднее значение равно 0. Происходит то, что мы постоянно видим больше -RandMax / 2   -  person user2161457    schedule 12.03.2013
comment
@CrisStringfellow Я не думаю, что это сработает ... Когда Math.random () возвращает .5, результат вычисления должен быть 0. С вашим уравнением результат вычисления будет .5 * RandMax - 2 * RandMax = -1,5 * RandMax   -  person user2161457    schedule 12.03.2013
comment
@ user2161457 вы делаете линейное преобразование, сдвиг и масштабирование неправильно. Тебе нужно этому научиться. stackoverflow .com / questions / 929103 /.   -  person Cris Stringfellow    schedule 12.03.2013
comment
Я не это пытаюсь делать. Я просто беру среднее значение группы случайных чисел между двумя конкретными значениями. Без изменения шкалы, без преобразования значений.   -  person user2161457    schedule 12.03.2013
comment
Ваша формула выглядит разумной (при условии, что величина RandMin и RandMax всегда будет равной). Возможно, вам стоит отнести это на math.stackexchange.com :-)   -  person Aaron Blenkush    schedule 12.03.2013


Ответы (1)


Из-за стандарта с плавающей запятой, который реализует Javascript, выполнение арифметики с десятичными значениями, мягко говоря, ошибочно ...

Один из способов решения проблемы - преобразовать десятичные дроби в целые числа путем умножения на 100, выполнения математических расчетов и последующего деления на 100.

Это хорошо работает, только если у вас не более двух десятичных знаков. Если вам требуется более высокая точность, я бы порекомендовал для этой части другой язык, кроме Javascript.

person Tutan Ramen    schedule 12.03.2013
comment
Хороший ответ. Мне не нужна более высокая точность, чем 2 десятичных знака. Я попробую это и посмотрю, исправит ли это. - person user2161457; 12.03.2013