Я ищу генератор случайных чисел, который может быть смещен. Например, скажите, что я хочу случайное число между 1-5 с вероятностью тем, чтобы быть:
1: Подходит 20% времени
2: Подходит 10% времени
3: Подходит 40% времени
4: Подходит 25% времени
5: Подходит 5% времени
Есть ли что-нибудь в стандартной библиотеке или других библиотеках там, которые сделали бы это? С другой стороны, есть ли эффективный способ сделать это самостоятельно?
Библиотека случайных чисел Boost предоставляет возможность задавать различные распределения форм для вашего генератора. Это отличная библиотека - см. http://www.boost.org/doc/libs/1_42_0/libs/random/index.html.
Почему бы вам просто не использовать обычный генератор случайных чисел, который возвращает число от 0,0 до 1,0, и обернуть его другой функцией, которая возвращает число в соответствии с ваши требования?
например
double biased (double seed) {
if (seed >= 0.0 && seed <0.2) return 1;
else if ...
}
Лучший способ, вероятно, просто взять обычный несмещенный генератор случайных чисел, а затем вернуться на основе интервала, в который попадает его значение.
Просто оператор if, который дает 1 для 0: 0,2, 2 для 0,2: 0,3, 3 для 0,3: 0,7, 4 для 0,7: 0,95 и 5 для 0,95: 1. Лучше всего сделать либо нижнюю, либо верхнюю границу интервала включительно, а другую - исключить.
int biasedRandom(){
double i = randomNumber();
if(i<= 0.2){return 1;}
else if(i <= 0.3){return 2;}
else if(i <= 0.7){return 3;}
else if(i <= 0.95){return 4;}
else{return 5;}
}
Что-то в этом роде.
Бросьте случайное действительное число x в [0,1], , если 0
], если 0,2
См. здесь для решения общей проблемы.
Для вашей проблемы просто равномерно выберите случайный элемент из этого списка:
[1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5]
В общем, проверьте этот ответ: Взвешенные случайные числа
В TR1 и C++0x есть
заголовок, который содержит discrete_distribution
класс для генерации таких чисел, среди прочих.
Вы также можете ознакомиться с библиотекой GSL, которая содержит гораздо больше случайных распределений (и генераторов случайных чисел), чем стандартная библиотека
. (Но учтите, что GSL использует GPLv3.)
То, что вы описываете, является реализацией генератора случайных чисел, который берет данные из определенного распределения вероятности. Например, генератор чисел с гауссовым распределением должен выдавать случайные числа таким образом, чтобы вероятность конкретного числа, x, была пропорциональна
(источник: wikimedia.org)
.
В общем случае подход заключается в том, чтобы взять выборку из равномерного случайного распределения, а затем выбрать значение кумулятивной функции распределения (CDF) желаемого распределения в этом месте выборки. В случае нормального гаусса возьмите случайное число x из равномерного распределения (именно так должны выдавать стандартные генераторы случайных чисел), а затем выберите в качестве случайного значения с гауссовым распределением. В вашем случае CDF, которую вы описываете, представляет собой кусочно-непрерывную ступенчатую функцию, которая может быть реализована с помощью любого из многих (правильных) ответов, которые вы уже получили.
Конечно, это все мелочи. Что вы должны делать, так это использовать библиотеку, которая уже делает это за вас. Статистика и генерация случайных чисел не являются тривиальными, и нет необходимости изобретать колесо. Смотрите ответ Нила (и ознакомьтесь с библиотекой Boost random number).
Кенни дал подходящий ответ, учитывающий ваше конкретное распределение частот.
Более общий ответ работает с CDF - кумулятивной функцией распределения - для данных и использует равномерное случайное число для выбора значения внутри распределения.