如果要从 vector elem
中选择一个v
,且其概率与成员值成正比,则需要实现一种称为fitness-proportionate或轮盘赌轮选择的选择方案。
要实现此目的,您可以首先根据数据成员的值创建一个“轮盘”:
std::vector<double> wheel, probs;
// extract the probabilities
std::transform(std::begin(v), std::end(v),
std::back_inserter(probs),
[](auto const & e) { return e.probability ; });
// then create the roulette wheel
std::partial_sum(std::begin(probs), std::end(probs),
std::back_inserter(wheel));
现在,只需做出选择,您就可以旋转
wheel
,并查看其落在车轮的哪个索引上。给定
wheel
的构造,降落在任何索引上的概率与
probability
中相同索引处的
elem
的
v
值成比例。
// create the random spinner, and uniformly distributed tip
std::mt19937 spinner;
std::uniform_real_distribution<double> tip(0., 1.); // since the sum is 1.
// In general, the second argument can be wheel.back()
// spin the wheel and selects an elem
auto spin = [&] {
auto choice = std::lower_bound(std::begin(wheel), std::end(wheel),
tip(spinner));
return v[std::distance(std::begin(wheel), choice)];
};
现在,您可以生成任意大小的新 vector 。
// spin the wheel N times to generate next population
std::vector<elem> new_v;
std::generate_n(std::back_inserter(new_v), N, spin);
请注意,如果要生成不重复元素的新 vector ,则必须付出更多努力以确保选择仍然是随机分布的。您要生成的新 vector 的大小也会影响此选择。