Я в основном stucked на довольно простую задачу:Работа с нормальным (гауссовым) распределением
Toss N монет и обнаружить, сколько из них участки головы
производительность Решение не должно зависеть от N, поэтому мы не можем просто позвонить Math.random() < 0.5
N раз. Очевидно, что для спасения есть распределение Гаусса.
Я использовал метод Бокса-Мюллера для него:
function gaussian_random(mean, variance) {
var s;
var x;
var y;
do {
x = Math.random() * 2.0 - 1.0;
y = Math.random() * 2.0 - 1.0;
s = Math.pow(x, 2) + Math.pow(y, 2);
} while ((s > 1) || (s == 0));
var gaussian = x * Math.sqrt(-2*Math.log(s)/s);
return mean + gaussian * Math.sqrt(variance);
}
Математика говорит, что означают из N бросков монеты является N/2
и дисперсия является N/4
Затем я сделал тест, который бросает N монет М раз, давая минимальное, максимальное и среднее количество головок.
Я сравнивал результаты наивного подхода (Math.random()
много раз) и подход Гаусса Бокса-Мюллера.
Существует типичный выход тестов:
Toss 1000 coins, 10000 times
Straight method:
Elapsed time: 127.330 ms
Minimum: 434
Maximum: 558
Average: 500.0306
Box-Muller method:
Elapsed time: 2.575 ms
Minimum: 438.0112461962819
Maximum: 562.9739632480057
Average: 499.96195358695064
Toss 10 coins, 10000 times
Straight method:
Elapsed time: 2.100 ms
Minimum: 0
Maximum: 10
Average: 5.024
Box-Muller method:
Elapsed time: 2.270 ms
Minimum: -1.1728354576573263
Maximum: 11.169478925333504
Average: 5.010078819562535
Как мы можем видеть на N = 1000
он подходит почти идеально.
BUT, on N = 10
Box-Muller сходит с ума: он позволяет получить такие результаты тестов, где я могу получить (довольно редко, но это возможно) 11.17 головок из 10 монетных монет! :)
Несомненно, я делаю что-то неправильно. Но что именно?
Существует source of test, и ссылка на launch it
Обновлено x2:, кажется, раньше я не описал проблему наилучшим образом. Существует общая версия этого:
Как получить выборочные среднее из N однородных случайных величины (либо дискретных или непрерывных) в амортизационном постоянная время. Гауссовское распределение эффективно для больших N, но есть ли способ заставить его работать на небольших N? Или на каком именно N решение должно переключиться с гауссовского метода на какой-нибудь другой (для простого сравнения).
Я бы сказал, что вам нужно [биномиальное распространение] (https://en.wikipedia.org/wiki/Binomial_distribution) с 'p = 0.5', а не гауссовым. Если N достаточно велико, нормаль является разумной аппроксимацией биномиального распределения. Но, конечно, не для 'N = 10'. –
с точки зрения Box-Muller нет ничего сумасшедшего. Он не имеет средств для монет и дает «разлив» для расчета на основе параметров, которые вы предоставили. На низком уровне выборки этот разлив нарушает границы вашей выборки, потому что формулы ничего не знают о них. –
@StefanZobel в действительности, 'p = 0.5' случай планируется сделать первым шагом; Далее я хочу решить проблему для любых 'p' и' N'. Вот почему биномиальное распределение не подходит, я ищу общее решение. @SergeyGrinev Я понимаю, что Box-Muller делает именно то, что он должен был сделать. Однако его ограничение использования было неожиданным. – augur