В вашем вопросе не указывается, какой дистрибутив использовать. Одним из вариантов (многих) является использование (negative) exponential distribution. Это распределение параметризуется параметром & lambda;. Для каждого значения & lambda;, максимальный результат является неограниченным (который должен быть обработан, чтобы вернуть результаты только в диапазоне, указанном)
(из Википедии, По Skbkekas, CC BY 3.0)
так что любой & lambda; теоретически может работать; Однако свойства ВПР
(из Википедии, By Skbkekas, CC BY 3.0)
следует, что он платит, чтобы выбрать что-то в порядке 1/(до - от + 1).
Следующий класс работает как стандартное распределение библиотек. Внутри он генерирует числа в цикле, пока не будет получен результат в [from, to].
#include <iostream>
#include <iomanip>
#include <string>
#include <map>
#include <random>
class bounded_discrete_exponential_dist {
public:
explicit bounded_discrete_exponential_dist(std::size_t from, std::size_t to) :
m_from{from}, m_to{to}, m_d{0.5/(to - from + 1)} {}
explicit bounded_discrete_exponential_dist(std::size_t from, std::size_t to, double factor) :
m_from{from}, m_to{to}, m_d{factor} {}
template<class Gen>
std::size_t operator()(Gen &gen) {
while(true) {
const auto r = m_from + static_cast<std::size_t>(m_d(gen));
if(r <= m_to)
return r;
}
}
private:
std::size_t m_from, m_to;
std::exponential_distribution<> m_d;
};
Ниже приведен пример использования его:
int main()
{
std::random_device rd;
std::mt19937 gen(rd());
bounded_discrete_exponential_dist d{1, 10};
std::vector<std::size_t> hist(10, 0);
for(std::size_t i = 0; i < 99999; ++i)
++hist[d(gen) - 1];
for(auto h: hist)
std::cout << std::string(static_cast<std::size_t>(80 * h/99999.), '+') << std::endl;
}
При запуске он выводит гистограмму так:
$ ./a.out
++++++++++
+++++++++
+++++++++
++++++++
+++++++
+++++++
+++++++
+++++++
++++++
++++++
Вы ищете распределение zipf? http://stackoverflow.com/questions/9983239/how-to-generate-zipf-distributed-numbers-efficiently – HazemGomaa