1
votes

I have an interesting question, namely

by using the famous mersenne twister std::mt19937 r in the standard library (or any other random generator) and setting it up with a seed as r.seed(4) for example it is possible to obtain uniformly random generated numbers (in the range uint_fast32_t provides).

What exactly happens if we loop through the seed from say 1 till 100 and generate the first random number, is this sequence still uniformly distributed or not?

for(int i = 0;i<100;i++){
   r.seed(i);
   int v = r();
}

I have some algorithm which would be much easier to implement by using this trick instead of generating the number in the usual way (without resetting the seed everytime).

I actually don't believe that by misusing the generator like that, that the uniformity of the sequence can be maintained anymore.

Does anybody has the expertise to give some reasoning about this?

Thanks a lot!

1
Those will be 100 entirely deterministic numbers. What does "uniform" mean in this context?Oliver Charlesworth
Mersenne twister random number engine: A pseudo-random number generator engine that produces unsigned integer numbers in the closed interval [0,2w-1]. The algorithm used by this engine is optimized to compute large series of numbers (such as in Monte Carlo experiments) with an almost uniform distribution in the range. cplusplus.com/reference/random/mersenne_twister_engineGabriel
Assuming your source is correct, and the output generated is more or less uniformly distributed, why on earth would you think this property will hold if you keep resetting the state? You do realize previous state is used in the generation of the result? In any case, why even involve the PRNG? Create a test program in which you seed the mt19937 once with every integer in the range [0,100), generate a single random number, and note the result. Then stick those in an array and use it in your real application.Praetorian
I don't think the property will hold, thats what I said, but anyway if It WOULD (i dont know) my algorithm is much faster, because I can use this fact that it still remains uniformly distributedGabriel

1 Answers

3
votes

This code does what you say, reseting the seed between each number generation :

#include <iostream>
#include <random>

int main ()
{
    std::mt19937 r; 

    for(int i = 0;i<10;i++){
       r.seed(i);
       int v = r();
        std::cout << v << std::endl;
    }
    return 0;
}

The output of this program is deterministic. You keep reseting the state between each generation (and this state is used to generate the next random number). You have absolutely no guarantee about the distribution, or the uniformity, of numbers generated from different mersenne sequences (again, a new sequence being started each time you reset the seed).

If your goal is to generate a uniform distribution constrained in an interval, use std::uniform_real_distribution :

Example from en.cppreference.com :

#include <random>
#include <iostream>

int main()
{
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_real_distribution<> dis(1, 2);
    for (int n = 0; n < 10; ++n) {
        std::cout << dis(gen) << ' ';
    }
    std::cout << '\n';
}

It is defined in the C++ standard, section § 26.5.8.2.2 :

A uniform_real_distribution random number distribution produces random numbers x , a ≤ x < b , distributed according to the constant probability density function p ( x | a,b ) = 1 / ( b − a )