ถ้าน้ำหนักของคุณเปลี่ยนแปลงช้ากว่าที่วาด 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
จะคำนวณผลรวมสะสมทั้งหมดของการเริ่มต้น โดยปกติแล้วคุณต้องการสิ่งนั้นเนื่องจากความเร็วในการสุ่มตัวอย่างสำหรับต้นทุน O (N) เพียงครั้งเดียว แต่สำหรับการกระจายที่เปลี่ยนแปลงอย่างรวดเร็วจะต้องเสียค่าใช้จ่ายในการคำนวณ (และหน่วยความจำ) อย่างหนัก ตัวอย่างเช่นหากน้ำหนักแสดงจำนวนรายการที่มีและทุกครั้งที่คุณวาดหนึ่งชิ้นคุณลบออกคุณอาจต้องการอัลกอริทึมที่กำหนดเอง
คำตอบของ Will 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;
}