Does std::mt19937 require warmup?

前端 未结 3 1424
遇见更好的自我
遇见更好的自我 2020-11-28 04:10

I\'ve read that many pseudo-random number generators require many samples in ordered to be \"warmed up\". Is that the case when using std::random_device to seed std::mt19937

3条回答
  •  南笙
    南笙 (楼主)
    2020-11-28 04:36

    If you seed with just one 32-bit value, all you will ever get is one of the same 2^32 trajectories through state-space. If you use a PRNG with KiBs of state, then you should probably seed all of it. As described in the comments to @bames63' answer, using std::seed_seq is probably not a good idea if you want to init the whole state with random numbers. Sadly, std::random_device does not conform to the SeedSequence concept, but you can write a wrapper that does:

    #include 
    #include 
    #include 
    #include 
    
    class random_device_wrapper {
        std::random_device *m_dev;
    public:
        using result_type = std::random_device::result_type;
        explicit random_device_wrapper(std::random_device &dev) : m_dev(&dev) {}
        template 
        void generate(RandomAccessIterator first, RandomAccessIterator last) {
            std::generate(first, last, std::ref(*m_dev));
      }
    };
    
    int main() {
    
        auto rd = std::random_device{};
        auto seedseq = random_device_wrapper{rd};
        auto mt = std::mt19937{seedseq};
        for (auto i = 100; i; --i)
            std::cout << mt() << std::endl;
    
    }
    

    This works at least until you enable concepts. Depending on whether your compiler knows about SeedSequence as a C++20 concept, it may fail to work because we're supplying only the missing generate() method, nothing else. In duck-typed template programming, that code is sufficient, though, because the PRNG does not store the seed sequence object.

提交回复
热议问题