Нуждаюсь в помощи генерируя дискретные случайные числа от распределения

Я просто добавил

     android:configChanges="keyboard|keyboardHidden|orientation"

в файл манифеста, а не добавил никакой метод onConfigurationChanged в мою деятельность.

Так что каждый раз, когда клавиатура выдвигается или ничего не происходит .

9
задан Gordon Gustafson 28 July 2009 в 23:53
поделиться

5 ответов

What do you need this for? Can you do it the craps player's way?

Generate two random integers in the range of 2 to 5 (inclusive, of course) and add them together. Or flip a coin (0,1) six times and add 4 to the result.

Summing multiple dice produces a normal distribution (a "bell curve"), while eliminating high or low throws can be used to skew the distribution in various ways.

The key is you are going for discrete numbers (and I hope you mean integers by that). Multiple dice throws famously generate a normal distribution. In fact, I think that's how we were first introduced to the Gaussian curve in school.


Of course the more throws, the more closely you approximate the bell curve. Rolling a single die gives a flat line. Rolling two dice just creates a ramp up and down that isn't terribly close to a bell. Six coin flips gets you closer.

So consider this...

If I understand your question correctly, you only have seven possible outcomes--the integers (4,5,6,7,8,9,10). You can set up an array of seven probabilities to approximate any distribution you like.

4
ответ дан 4 December 2019 в 22:29
поделиться

Многие фреймворки и библиотеки имеют эту встроенную функцию.

Также, как и TokenMacGuy сказал, что нормальное распределение не характеризуется интервалом ] он определяется двумя параметрами: средним μ и стандартным отклонением σ. С обоими этими параметрами вы можете ограничить определенный квантиль распределения определенным интервалом, так что 95% всех точек попадают в этот интервал. Но полностью ограничить его любым интервалом, кроме (−∞, ∞), невозможно.

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

  • Преобразование Бокса-Мюллера , вероятно, является самым простым, хотя и не совсем быстрым для вычисления. В зависимости от количества необходимых чисел, его должно быть достаточно, хотя и определенно очень легко написать.

  • Другой вариант - полярный метод Марсальи , который обычно быстрее 1 .

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

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


Для искажения вашего распределения я бы просто использовал обычное нормальное распределение, выбор μ и σ соответственно для одной стороны вашей кривой, а затем определение, с какой стороны от желаемого значения, означает, что точка упала, растягивая ее соответствующим образом, чтобы соответствовать желаемому распределению.


Для генерация только целых чисел Я бы посоветовал вам просто округлить до ближайшего целого числа, когда случайное число попадает в желаемый интервал, и отклонить его, если это не так (тогда рисование нового случайного числа). Таким образом, вы не будете искусственно искажать распределение (например, если бы вы ограничивали значения 4 или 10 соответственно).


1 При тестировании с намеренно неправильными генераторами случайных чисел (да, хуже, чем RANDU ) Я заметил, что полярный метод приводит к бесконечному циклу, отклоняющему каждый отсчет. Выиграл'

1
ответ дан 4 December 2019 в 22:29
поделиться

Да, есть сложные математические решения, но для «простых, но практичных» я бы согласился с комментарием Носредны. Для простого Java-решения:

Random random=new Random();
public int bell7()
{
  int n=4;
  for (int x=0;x<6;++x)
    n+=random.nextInt(2);
  return n;
}

Если вы не Java-человек, Random.nextInt (n) возвращает случайное целое число от 0 до n-1. Я думаю, что все остальное должно быть похоже на то, что вы видели бы на любом языке программирования.

Если бы диапазон был большим, то вместо nextInt (2) я бы использовал большее число, чтобы было меньше итераций цикла в зависимости от частоты вызовов и требований к производительности.

1
ответ дан 4 December 2019 в 22:29
поделиться

Нормальное распределение не описывается его конечными точками. Обычно это описывается средним значением (которое вы дали равным 7) и его стандартным отклонением. Важной особенностью этого является то, что из этого распределения можно получить значение далеко за пределами ожидаемого диапазона, хотя это будет исчезающе редко по мере удаления от среднего.

Обычным способом получения значения из распределения является генерация случайного значения из равномерного распределения, что довольно легко сделать, например, с помощью rand () , а затем использовать это как аргумент кумулятивной функции распределения , , которая отображает вероятности на верхние границы. Для стандартного распределения эта функция имеет вид

F(x) = 0.5 - 0.5*erf( (x-μ)/(σ * sqrt(2.0)))

, где erf () - это функция ошибок , которая может быть описана рядом Тейлора:

erf (z) = 2.0 / sqrt (2.0) * Σ n = 0 ((-1) n z 2n + 1 ) / (n! (2n + 1))

Я оставлю это как упражнение, чтобы перевести это на C.

Если вы предпочитаете не участвовать в этом упражнении, вы можете рассмотреть возможность использования Научной библиотеки Gnu , которая среди многих других функций имеет метод генерации случайных чисел в одном из многих распространенных распределений, одним из которых является распределение Гаусса (подсказка).

Очевидно, все эти функции возвращают значения с плавающей запятой. Вам придется использовать некоторую стратегию округления, чтобы преобразовать в дискретное значение. Полезный (но наивный) подход - просто привести к целому числу.

0) * Σ n = 0 ((-1) n z 2n + 1 ) / (n! (2n + 1))

Я оставлю это как упражнение, чтобы перевести это на C.

Если вы предпочитаете не участвовать в этом упражнении, вы можете рассмотреть возможность использования Научной библиотеки Gnu , которая среди многих других функций , имеет метод генерации случайных чисел в одном из многих распространенных распределений, одним из которых является распределение Гаусса (подсказка).

Очевидно, все эти функции возвращают значения с плавающей запятой. Вам придется использовать некоторую стратегию округления, чтобы преобразовать в дискретное значение. Полезный (но наивный) подход - просто привести к целому числу.

0) * Σ n = 0 ((-1) n z 2n + 1 ) / (n! (2n + 1))

Я оставлю это как упражнение, чтобы перевести это на C.

Если вы предпочитаете не участвовать в этом упражнении, вы можете рассмотреть возможность использования Научной библиотеки Gnu , которая среди многих других функций , имеет метод генерации случайных чисел в одном из многих распространенных распределений, одним из которых является распределение Гаусса (подсказка).

Очевидно, все эти функции возвращают значения с плавающей запятой. Вам придется использовать некоторую стратегию округления, чтобы преобразовать в дискретное значение. Полезный (но наивный) подход - просто привести к целому числу.

вы можете рассмотреть возможность использования Научной библиотеки Gnu , в которой, среди многих других функций, есть методика генерации случайных чисел в одном из многих распространенных распределений, одним из которых является распределение Гаусса (подсказка).

Очевидно, , все эти функции возвращают значения с плавающей запятой. Вам нужно будет использовать некоторую стратегию округления, чтобы преобразовать в дискретное значение. Полезный (но наивный) подход - просто привести к целому числу.

вы можете рассмотреть возможность использования Научной библиотеки Gnu , в которой, среди многих других функций, есть методика генерации случайных чисел в одном из многих распространенных распределений, одним из которых является распределение Гаусса (подсказка).

Очевидно, , все эти функции возвращают значения с плавающей запятой. Вам придется использовать некоторую стратегию округления, чтобы преобразовать в дискретное значение. Полезный (но наивный) подход - просто привести к целому числу.

Полезный (но наивный) подход - просто привести к целому числу.

Полезный (но наивный) подход - просто привести к целому числу.

1
ответ дан 4 December 2019 в 22:29
поделиться

Дэн Дайер и Джей совершенно правы. На самом деле вам нужно биномиальное распределение, а не нормальное. Форма биномиального распределения очень похожа на нормальное распределение, но оно дискретное и ограниченное, тогда как нормальное распределение является непрерывным и неограниченным.

Код Джея генерирует биномиальное распределение с 6 попытками и 50% вероятностью успеха в каждом. испытание. Если вы хотите «исказить» свое распределение, просто измените строку, определяющую, следует ли прибавлять 1 к n, чтобы вероятность была отличной от 50%.

1
ответ дан 4 December 2019 в 22:29
поделиться
Другие вопросы по тегам:

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