如果您想从向量v 中选择一个概率与成员值成正比的elem,您需要实施称为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 的构造,任何索引的着陆概率与elem 在v 中同一索引处的probability 值成正比。
// 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)];
};
现在您可以生成任意大小的新向量。
// spin the wheel N times to generate next population
std::vector<elem> new_v;
std::generate_n(std::back_inserter(new_v), N, spin);
注意,如果你想生成一个新的向量不重复元素,你将不得不付出更多的努力来确保选择仍然是随机分布的。此选择还会受到您要生成的新向量大小的影响。