Which C++ random number engines have a O(1) discard function?

后端 未结 3 1336
佛祖请我去吃肉
佛祖请我去吃肉 2021-02-20 00:42

Since C++11 there are a number of std random number engines. One of the member functions they implement is void discard(int long long z) which skips over z randomly

3条回答
  •  说谎
    说谎 (楼主)
    2021-02-20 01:16

    I don't think such things exists at all. My heuristic conclusion is that O(1)-jump RNG is basically a hash, with all that this implies (e.g. it might not be "good" RNG at all).

    But even if you are asking about O(log z) I don't see that implemented in the STL. In GCC's all the discard functions I was able to grep are all simple loops.

          discard(unsigned long long __z)
          {
            for (; __z != 0ULL; --__z)
              (*this)();
          }
    

    Which is not only sad but also misleading since discard should exists only if there is an efficient way to do it.

    The only non trivial one is mersenne (below) but it is still O(z).

        discard(unsigned long long __z)
        {
          while (__z > state_size - _M_p)
        {
          __z -= state_size - _M_p;
          _M_gen_rand();
        }
          _M_p += __z;
        }
    

    Boost's Mersenne, has a skip function but it is only called for skips larger than a (default of) 10000000 (!?). Which already tells me that that the skip is very heavy computationally (even if it is O(log z)). https://www.boost.org/doc/libs/1_72_0/boost/random/mersenne_twister.hpp

    Finally, Trust has an efficient discard for linear congruential apparently, but only in the case c=0. (Which I am not sure if it makes it less useful as a RNG.) https://thrust.github.io/doc/classthrust_1_1random_1_1linear__congruential__engine_aec05b19d2a85d02f1ff437791ea4dd68.html#aec05b19d2a85d02f1ff437791ea4dd68

提交回复
热议问题