Search code examples
c++randomsampling

How to randomly pick element from an array with different probabilities in C++


Suppose I have a vector<Point> p of some objects.

I can pick a uniformly random by simply p[rand() % p.size()].

Now suppose I have another same-sized vector of doubles vector <double> chances.

I want to randomly sample from p with each element having a probability analogous to its value in chances (which may not be summing to 1.0). How can I achieve that in C++?


Solution

  • You are looking for std::discrete_distribution. Forget about rand().

    #include <random>
    #include <vector>
    
    struct Point {};
    
    int main() {
        std::mt19937 gen(std::random_device{}());
    
        std::vector<double> chances{1.0, 2.0, 3.0};
        // Initialize to same length.
        std::vector<Point> points(chances.size());
        // size_t is suitable for indexing.
        std::discrete_distribution<std::size_t> d{chances.begin(), chances.end()};
    
        auto sampled_value = points[d(gen)];
    }
    

    Conveniently for you, the weights do not have to sum to 1.