jeudi 7 mai 2015

Distributions and internal state

On Stackoverflow there are many questions about generating uniformly distributed integers from a-priory unknown ranges. E.g.

The typical solution is something like:

inline std::mt19937 &engine()
{
  thread_local std::mt19937 eng;
  return eng;
}

int get_int_from_range(int from, int to)
{
  std::uniform_int_distribution<int> dist(from, to);
  return dist(engine());
}

Given that a distribution should be a lightweight object and there aren't performance concerns recreating it multiple times, it seems that even simple distribution may very well and usually will have some internal state.

So I was wondering if interfering with how the distribution works by constantly resetting it (i.e. recreating the distribution at every call of get_int_from_range) I get properly distributed results.

There's a long discussion between Pete Becker and Steve Jessop but without a final word. In other related questions (Should I keep the random distribution object instance or can I always recreate it?) the "problem" of the internal state doesn't seem very important.

Does the C++ standard make any guarantee regarding this topic?

Is the following implementation (from N4316 - std::rand replacement) somewhat more reliable?

int get_int_from_range(int from, int to)
{
  using distribution_type = std::uniform_int_distribution<int>;
  using param_type = typename distribution_type::param_type;

  thread_local std::uniform_int_distribution<int> dist;
  return dist(engine(), param_type(from, to));    
}




Aucun commentaire:

Enregistrer un commentaire