Лучший способ рассчитать, есть ли вероятность 1/4, что что-то произойдет в C++?
-
11-07-2019 - |
Вопрос
Мне было интересно, есть ли умный способ узнать
Вероятность того, что что-то произойдет, составляет 1/4.
Я знаю, что мы можем сделать это с помощью rand() % 4 и проверить, равно ли оно 0, но есть ли способ без использования rand()?На С++, спасибо.
Нет правильного решения
Другие советы
Если вы имеете в виду, что хотите избежать присущей многим дрянностям rand()
реализации, вам, вероятно, следует изучить библиотека Boost Random, который имеет несколько высококачественных PRNG (генераторов псевдослучайных чисел) и множество способов управления выводом.Эта библиотека также присутствует в несколько измененном виде в std::tr1
.
Никогда никогда используйте% для усечения значения PRNG в диапазоне. Большинство PRNG имеют относительно неслучайные биты младшего разряда.
Для вашего случая используйте деление (RAND_MAX / n), как предлагает BCS.
rand() < RAND_MAX/n;
выберите лучший rand (), чем C, если вам не нравится стандартный rand () в C.
Вы можете написать свой собственный рэнд. (не делай этого).
Вы могли бы взять счет тик. (не делайте это слишком часто).
Вы можете просто посчитать, и каждый четвертый вызов вернет истину.
Возможно, вам следует просто вызвать rand ().
Я немного знаю C ++, поэтому могу ошибаться. Но, похоже, rand()
возвращает значение между 0
и RAND_MAX-1
. Поэтому, возможно, вы могли бы сделать что-то вроде этого:
double odds = .25;
if(rand() <= RAND_MAX * odds) {
// there should be .25 chance of entering this condition
}
PS: Может быть, это требует кастинга.
Почему бы не использовать rand ()? Если вас беспокоит & Quot; true & Quot; случайность против псевдослучайности, вы можете попробовать используя физические источники случайных битов . Гораздо сложнее и, как правило, не нужно. Р>
Вы можете использовать другой тип ГСЧ, например Mersenne twister , который имеет лучшую общую энтропию , Я также слышал хорошие слова о множественном использовании с Carry RNG.
4 — частный случай.Вы можете предположить, что ваш PRNG имеет 50% шансов вывести четное число, что, я думаю, справедливо для LCG libc (rand).Таким образом, вероятность вывода четного числа дважды равна 25%.
Поэтому...
bool rand_afourth(void)
{
return !!((rand() & 1) & (rand() & 1));
}
А теперь для педантов...
Что вы хотите сделать, так это создать равномерный случайный результат, но ограниченный определенным диапазоном, в данном случае энтропией 4.Если ваш ГПСЧ имеет, скажем, 32-битную энтропию, вы не можете быть уверены, что вычисление выходного мод 4 будет работать так, как ожидалось.Это потребует немного больше работы.
К счастью, эта работа уже реализована в библиотеке boost.
boost::uniform_int<> aFourth(1,4)
И вы, например, говорите «ОК» каждый раз, когда получаете 1 (или 2, 3, 4, как вам нравится).
Но вы можете не захотеть использовать библиотеку boost.Тогда просто посмотрите код Uniform_int и воспроизвести поведение.Таланты подражают, гении воруют.;)
Хм ... напиши свой rand()
? Вам понадобится некоторая разновидность случайной функции!
Пытаться:
static int r = 0;
: : :
if ((r = (r+1)%4) == 0) {
// do something.
}
Затем вы обнаружите, что это дает вам идеальную вероятность 25% того, что что-то произойдет (при условии, что вы выполните оператор if кратное четырем раза.
</humor>