Лучший способ рассчитать, если есть вероятность 1/4, что-то случится в C ++? - PullRequest
2 голосов
/ 29 ноября 2008

Мне было интересно, есть ли умный способ узнать

Вероятность того, что что-то случится, составляет 1/4.

Я знаю, что мы можем сделать это с помощью rand ()% 4 и проверить, равно ли оно 0, но есть ли способ без использования rand ()? На С ++ спасибо.

Ответы [ 11 ]

11 голосов
/ 29 ноября 2008

Если вы имеете в виду, что хотите избежать присущей многим реализациям rand() глупости, вам, вероятно, стоит заглянуть в библиотеку Boost Random , которая имеет несколько высококачественных pRNG (генераторов псевдослучайных чисел) и много способов контролировать вывод. Эта библиотека также присутствует в слегка измененном виде в std::tr1.

9 голосов
/ 29 ноября 2008

Никогда когда-либо используйте% для усечения значения PRNG в диапазоне. Большинство PRNG имеют относительно неслучайные биты младшего разряда.

Для вашего случая используйте деление (RAND_MAX / n), как предлагает BCS.

4 голосов
/ 29 ноября 2008
rand() < RAND_MAX/n;

выберите лучший rand (), чем у C, если вам не нравится стандартный rand ().

4 голосов
/ 29 ноября 2008

random number generator

3 голосов
/ 29 ноября 2008

Я не знаю много C ++, поэтому я могу ошибаться. Но, похоже, rand() возвращает значение от 0 до RAND_MAX-1. Поэтому, возможно, вы могли бы сделать что-то вроде этого:

double odds = .25;

if(rand() <= RAND_MAX * odds) {
    // there should be .25 chance of entering this condition
}

PS: Может быть, для этого нужен кастинг.

3 голосов
/ 29 ноября 2008

Вы можете написать свой собственный ранд. (не делай этого).
Вы могли бы взять счет тик. (не делайте это слишком часто).
Вы можете просто посчитать, и каждый четвертый вызов вернет true.

Возможно, вам следует просто вызвать rand ().

1 голос
/ 29 ноября 2008

4 - особый случай. Вы можете предположить, что у вашего PRNG есть 50% шансов на вывод четного числа, что, как мне кажется, имеет место для LCG libc (rand). Следовательно, вероятность вывода четного числа дважды составляет 25%.

Поэтому ...

bool rand_afourth(void)
{
    return !!((rand() & 1) & (rand() & 1));
}

А теперь о педантике ...

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

К счастью, эта работа уже была реализована в библиотеке наддува.

boost::uniform_int<> aFourth(1,4)

И вы, например, говорите «ок» каждый раз, когда получаете 1 (или 2, 3, 4, как вам хочется).

Но вы не можете использовать библиотеку наддува. Затем просто посмотрите на кодiform_int и воспроизведите поведение. Таланты подражают, гении крадут. ;)

1 голос
/ 29 ноября 2008

Вы можете использовать другой тип ГСЧ, такой как Mersenne twister , который имеет лучшую общую энтропию. Я также слышал хорошие слова о Multuply с Carry RNG.

1 голос
/ 29 ноября 2008

Почему бы не использовать rand ()? Если вас беспокоит «истинная» случайность или псевдослучайность, вы можете попробовать , используя физические источники случайных битов . Гораздо сложнее и, как правило, не нужно.

0 голосов
/ 29 ноября 2008

Попробуйте:

static int r = 0;
: : :
if ((r = (r+1)%4) == 0) {
    // do something.
}

Тогда вы обнаружите, что это дает вам 25% вероятности того, что что-то случится (при условии, что вы выполняете оператор if кратный четырем разам.

...