Jika bobot Anda berubah lebih lambat daripada yang digambar, C ++ 11 discrete_distribution
akan menjadi yang termudah:
#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...
Perhatikan, bagaimanapun, bahwa c ++ 11 discrete_distribution
menghitung semua jumlah kumulatif saat inisialisasi. Biasanya, Anda menginginkannya karena mempercepat waktu pengambilan sampel untuk biaya satu kali O (N). Tetapi untuk distribusi yang berubah dengan cepat, ini akan menimbulkan biaya perhitungan (dan memori) yang berat. Misalnya jika bobot mewakili berapa banyak item yang ada dan setiap kali Anda menggambarnya, Anda menghapusnya, Anda mungkin menginginkan algoritme khusus.
Jawaban Will https://stackoverflow.com/a/1761646/837451 menghindari overhead ini tetapi akan lebih lambat untuk diambil dari C ++ 11 karena tidak dapat menggunakan pencarian biner.
Untuk melihat bahwa ia melakukan ini, Anda dapat melihat baris yang relevan ( /usr/include/c++/5/bits/random.tcc
pada instalasi Ubuntu 16.04 + GCC 5.3 saya):
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;
}