Search code examples
c++randomrandom-seed

Multiple seeds for random C++


Is there a way to pass multiple amount of number (in my case 3) as seeds for random to work with? I need the result to be pseudo-random value which is lineary distributed, so I can't just use something as srand(x + y + z);, because srand((x+n) + y + z); will give the same result as srand(x + (y+n) + z); which is predictable.


Solution

  • This seems to be a job for the std::seed_seq class within the C++11 PRNG facilities.

    An object of this class is initialized with a number of input integer values, in your notations x,y,z, and is able to spread their “entropy” into an arbitrary number of output integer values, typically as large as the state of your pseudo-random generator. The spreading algorithm is way more complex than a simple addition of input values.

    Using the popular Mersenne Twister engine, we can prepare two generators that differ only by swapping y and z:

    #include  <string>
    #include  <iostream>
    #include  <random>
    #include  <algorithm>
    
    int main()
    {
        std::seed_seq seed1{314159, 26535, 897932};
        std::seed_seq seed2{314159, 897932, 26535};
    
        std::mt19937 gen1 (seed1);
        std::mt19937 gen2 (seed2);
    
    

    We can use these 2 generators to make, for example, random permutations of the Latin alphabet:

    
        std::string  str0{"ABCDEFGHIJKLMNOPQRSTUVWXYZ"};
        std::string  str1{str0};
        std::string  str2{str0};
    
        std::shuffle(str1.begin(), str1.end(), gen1);
        std::shuffle(str2.begin(), str2.end(), gen2);
    
        std::cout << "With gen1:  " << str1 << '\n';
        std::cout << "With gen2:  " << str2 << '\n';
    
        return EXIT_SUCCESS;
    }
    

    Test program output:

    With gen1:  XIUKCMQELBARJTNOYFDSPVHGWZ
    With gen2:  CRIXQYKHEPUSGJZNVAMWOTLDBF
    

    So we are getting 2 different permutations, thus proving that our 2 generators started from different states. The spreading algorithm is certainly more complex than a simple commutative addition.

    See also discussion here: SO-q22522829