If you want to pick an elem from the vector v with a probability proportional to the value of a member, you need to implement a selection scheme known as fitness-proportionate or roulette-wheel selection.
To implement this, you can first create a "roulette-wheel" based on the values of the data member:
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));
Now to make a single choice, you can spin the wheel, and see which index of the wheel it lands on. Given the construction of wheel, the probability of landing on any index is proportional to the probability value of the elem at that same index in 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)];
};
Now you can generate a new vector of whatever size you want.
// spin the wheel N times to generate next population
std::vector<elem> new_v;
std::generate_n(std::back_inserter(new_v), N, spin);
Note that if you want to generate a new vector without repeating elements, you will have to put in a little more effort to ensure that the choices are still randomly distributed. This choice will also be affected by the size of the new vector you want to generate.