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.
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