यदि आपका वजन अधिक धीरे-धीरे बदल जाता है, तो वे C ++ 11 discrete_distribution
सबसे आसान होने जा रहे हैं:
#include <random>
#include <vector>
std::vector<double> weights{90,56,4};
std::discrete_distribution<int> dist(std::begin(weights), std::end(weights));
std::mt19937 gen;
gen.seed(time(0));//if you want different results from different runs
int N = 100000;
std::vector<int> samples(N);
for(auto & i: samples)
i = dist(gen);
//do something with your samples...
हालाँकि, ध्यान दें कि c ++ 11 discrete_distribution
सभी संचयी योगों को आरंभीकरण पर गणना करता है। आमतौर पर, आप चाहते हैं कि क्योंकि यह एक समय ओ (एन) लागत के लिए नमूना समय को गति देता है। लेकिन तेजी से बदलते वितरण के लिए यह एक भारी गणना (और स्मृति) खर्च करेगा। उदाहरण के लिए यदि वेट ने दर्शाया कि कितने आइटम हैं और हर बार जब आप एक ड्रॉ करते हैं, तो आप इसे हटा देते हैं, आप शायद एक कस्टम एल्गोरिदम चाहते हैं।
विल का जवाब https://stackoverflow.com/a/1761646/837451 इस ओवरहेड से बचता है लेकिन C ++ 11 की तुलना में ड्रॉ करने के लिए धीमा होगा क्योंकि यह बाइनरी सर्च का उपयोग नहीं कर सकता है।
यह देखने के लिए कि यह ऐसा करता है, आप संबंधित लाइनें ( /usr/include/c++/5/bits/random.tcc
मेरे Ubuntu 16.04 + GCC 5.3 स्थापित पर) देख सकते हैं :
template<typename _IntType>
void
discrete_distribution<_IntType>::param_type::
_M_initialize()
{
if (_M_prob.size() < 2)
{
_M_prob.clear();
return;
}
const double __sum = std::accumulate(_M_prob.begin(),
_M_prob.end(), 0.0);
// Now normalize the probabilites.
__detail::__normalize(_M_prob.begin(), _M_prob.end(), _M_prob.begin(),
__sum);
// Accumulate partial sums.
_M_cp.reserve(_M_prob.size());
std::partial_sum(_M_prob.begin(), _M_prob.end(),
std::back_inserter(_M_cp));
// Make sure the last cumulative probability is one.
_M_cp[_M_cp.size() - 1] = 1.0;
}