How to define a vector of random engines with different seeds?

Viewed 97

Because I'm using multi-threading, I need to define multiple random engines, one for each thread.

If I knew there are 4 threads, I would do:

  std::default_random_engine generator1(1);
  std::default_random_engine generator2(10000);
  std::default_random_engine generator3(20000);
  std::default_random_engine generator4(30000);
  std::vector<std::default_random_engine> generators = 
    {generator1, generator2, generator3, generator4};

But how to do for an arbitrary number of threads? Sorry if this is obvious, I'm not familiar with C/C++.


EDIT

Hmm, maybe

std::vector<std::default_random_engine> generators(n);
for(i = 0; i < n; i++) {
  std::default_random_engine generator(seeds[i]);
  generators[i] = generator;
}
1 Answers

The example you gave seems to work on Compiler Explorer. Here's your function turned into a function spawning one generator and thread per CPU and giving the generator to a lambda using C++20.

#include <vector> // std::vector
#include <random> // std::default_random_engine
#include <thread> // std::thread
#include <cstdint> // std::size_t
#include <ranges> // std::ranges
#include <functional> // std::ref

void foo() {

auto exec = [](std::default_random_engine &random) {
    return random();
};

std::vector<std::default_random_engine> generators;
std::vector<std::thread> threads;
const std::size_t concurrency = std::max(1u, std::thread::hardware_concurrency());
threads.reserve(concurrency);
generators.reserve(concurrency);
for (const auto & i : std::ranges::views::iota(0u,concurrency) )
{
    generators.emplace_back(i * 1000);
    threads.emplace_back(exec, std::ref(generators.back()));
}
for (auto & t : threads )
{
    t.join();
}

} // void foo()
Related