Ağırlıklarınız çizildiğinden daha yavaş değişiyorsa, C ++ 11 discrete_distribution
en kolayı olacaktır:
#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...
Bununla birlikte, c ++ 11'in discrete_distribution
başlatma sırasında tüm kümülatif toplamları hesapladığını unutmayın. Genellikle bunu istersiniz çünkü örnekleme süresini bir kerelik O (N) maliyeti için hızlandırır. Ancak hızla değişen bir dağıtım için ağır bir hesaplama (ve hafıza) maliyetine yol açacaktır. Örneğin, ağırlıklar kaç tane öğe olduğunu gösteriyorsa ve her bir tane çizdiğinizde onu kaldırırsanız, muhtemelen özel bir algoritma isteyeceksiniz.
Will'in cevabı https://stackoverflow.com/a/1761646/837451 bu ek yükten kaçınır, ancak ikili aramayı kullanamadığı için C ++ 11'den daha yavaş çekilir.
Bunu yaptığını görmek için ilgili satırları görebilirsiniz ( /usr/include/c++/5/bits/random.tcc
Ubuntu 16.04 + GCC 5.3 kurulumumda):
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;
}