简体   繁体   中英

Using std::shuffle with custom Random Number Generator?

I see that std::shuffle takes an URNG argument. I am using a custom version of a generator (WELL512a) and would like to use it with std::shuffle .

My question is : Is it possible to use it with std::shuffle ? For example maybe by using URNG as a base class?

We can see from the cppreference documentation on std::shuffle that:

URNG must meet the requirements of UniformRandomNumberGenerator.

unfortunately the site does not document what those requirements are, so we need to go to the draft C++11 standard section 26.5.1.3 Uniform random number generator requirements which says the following:

  1. A uniform random number generator g of type G is a function object returning unsigned integer values such that each value in the range of possible results has (ideally) equal probability of being returned

  2. A class G satisfies the requirements of a uniform random number generator if the expressions shown in Table 116 are valid and have the indicated semantics, and if G also satisfies all other requirements of this section 26.5.1.3. In that Table and throughout this section:

    • T is the type named by G's associated result_type, and
    • g is a value of

Table 116 is summarized as follows:

  • G::result_type
    • return type is T
    • T is an unsigned integer type
  • g()
    • return type T
    • Returns a value in the closed interval [G::min(), G::max()].
  • G::min()
    • return type T
    • Denotes the least value potentially returned by operator().
  • G::max()
    • return type T
    • Denotes the greatest value potentially returned by operator().

The following relation shall hold: G::min() < G::max().

To clarify when it says T is an unsigned integer type it means one of the following types covered in section 3.9.1 Fundamental types which include:

  • unsigned char
  • unsigned short int
  • unsigned int
  • unsigned long int
  • unsigned long long int

This also include extended unsigned integer types such as uinit64_t , if your platform supports them.

URNG is the name of a template parameter - it's not a particular type. You need to implement an object that meets certain requirements, then you can pass it to std::shuffle . Something along these lines:

class MyRNG {
public:
  typedef size_t result_type;
  static size_t min() { return 0; }
  static size_t max() { return 42; }
  size_t operator()() {
    // generate a random number in the range [0, 42]
  }
};

std::shuffle(someVector.begin(), someVector.end(), MyRNG());

You may also consider using std::random_shuffle instead. That one takes an object r which can be called as r(n) for some integer n , and produce a random number in the range [0, n) .

std::random_shuffle is deprecated in C++14. std::random_shuffle在 C++14 中被弃用。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM