C++ random numbers are always the same - c++

I am currently stuck at generating random numbers during runtime. In Java, I just call Math.random() and I'm pretty much done (I just need a simple RNG). In C++, I have tried several ways to generate random numbers and always end up getting the same.
Currently, I am using the following method to get a random number between MIN and MAX:
unsigned int getRandomNumber(int min, int max){
std::mt19937 mt(1729);
std::uniform_int_distribution<int> dist(min, max);
return dist(mt);
}
I have an object that calls this function in its constructor and assigns the value returned to an attribute. I currently create five instances of this object and the random number is always the same. Setting a big range (1 - 1000) does not change this. The number is always the same. Security is not a concern, it is an extremely simple application.

A random number generator works with a seed. Basically it's a number that's set only once for the random number generator to work with. If you re-seed your random number generator each time you try to generate an number you will get the same number every time. You should create the std::mt19937 object only once.

unsigned int getRandomNumber(int min, int max){
static std::mt19937 mt(1729);
std::uniform_int_distribution<int> dist(min, max);
return dist(mt);
}
Making mt static will cause it to only be instantiated once, which means it will only be constructed once, which means it will only be seeded once. Even with this fix, you'll still get the same series of numbers each time you run the program, but they'll be different each time you call getRandomNumber in one single execution.
A much better solution would be to instantiate the mt variable elsewhere, and pass it in to this function as a parameter, that way you could manage how it is seeded with more code than just a constructor call. Typically you would seed with a value based on time. Lots of insight here.

Related

Random generator for guess game

I've been searching for a better solution than my own and I haven't really been able to find one that I understand or that works for me.
I have made the simple game where the computer randomly generates a number which you then guess a number and if it is higher the computer says higher and so on..
The problem is my randomly generated number, after looking up alot of information regarding the <random>, uniform_int_distribution and default_random_engine. I have found out that the computer generates a random number, but if you run the program again the same random number will be generated.
My solution:
uniform_int_distribution<unsigned> u(0,100); // code to randomly generate numbers between 0 and 100
default_random_engine e; // code to randomly generate numbers
size_t userInput; // User input to find out where to look in the vector
vector<int> randomNumbers; //vector to hold the random numbers
unsigned start = 0, ending = 101, cnt = 0; // used in the game not important right now
cout << "Please enter a number between 1 and 1000 for randomness" << endl;
cin >> userInput;
for(size_t i = 0; i < 1000; ++i){ //for loop to push numbers into the vector
randomNumbers.push_back(u(e));
}
unsigned guess = randomNumbers[userInput]; // finally the number that the user will have to guess in the game
My solution right now is to use a vector where I push alot of randomly generated numbers in then ask the user to type a number which then the computer uses for the game. But there should be a better way of doing this. And my question is therefore
Is there a better way to randomly generate numbers to use in the game?
Either use std::random_device in place of std::default_random_engine, or else think of a way to provide a different number to the engine each time it is run.
This number is called a "seed" and can be passed as an optional parameter to the constructor. Since std::default_random_engine is implementation-specific, and different engines do different things about seeding, you generally want to choose a specific engine if you're providing a seed. A deterministic pseudo-random number generator will produce the same sequence of outputs for any given seed, so you want to use a different seed each time.
For no-security uses like a guessing game, the most "obvious" thing to use as a seed is the current time. Generally speaking this is different each time the program is run, although obviously if you can run the program twice in less than the granularity of the clock then that's not the case. So using the time to seed your random engine is pretty limited but will do the job for a toy program.
That's because your random number is actually what we call a pseudorandom number generator
It's just a machine that given a starting number generates a large list of seemingly random numbers. As you don't provide a starting number, the generated list of random numbers is thus always the same. One easy way to fix this is to use the current time as a starting value or 'seed', which is an argument of the constructor of std::default_random_engine.
You can also use your machines real random number generator std::random_device as a replacement for std::default_random_engine
Why not simply:
#include <ctime> // for time()
#include <cstdlib> // for srand()
srand(time(NULL)); // Initializes the rand() function
int randomNumber = rand()%100; // Random number between 0 and 99.
What this does is the rand() seed is set at the current time, meaning that every execution of the program will have a different seed for rand().
Still just pseudo-random solution, though suitable for your purposes.

default_random_engine isn't randomizing values for me

When I run my function my x and y values stay the same every time it is run. I'm not sure if I am using the default_random_engine incorrectly or not. How can I get my x and y values using the dist(engine) to randomize and not be the same output every time the program executes?
A 'seed' is something that provides a pseudonumber generator with its 'randomness'. If you initialise it with the same seed, you will get the same 'random' pattern.
Here, you are probably passing the same seed in all the time.
Maybe you should define your function like this instead:
long double fn( long reps, default_random_engine & engine )
Declare a single instance of your random number generator when you run your program, and seed it once with a value that will always be different when your program starts (eg the system time). Then, pass the generator into any functions that require random number generation.

Random number generation in c++ using GMP

In java random number can get like
protected final static Random RANDOM = new Random(System.currentTimeMillis());
In c++ using GMP Library how it possible to generate random number?
I used code like
gmp_randstate_t s;
unsigned long seed;
seed = time(NULL);
gmp_randinit_default(s);
gmp_randseed_ui(s, seed);
mpz_class ran;
gmp_randclass rr(s);
ran =rr.get_z_bits(125);
long int random=ran.get_ui();
But i dont get random number.
Please help me.
First, there is no gmp_randclass constructor that takes a gmp_randstate instance, so your code didn't compile for me. The recommended way to construct a gmp_randclass instance is using gmp_randinit_default, like this:
gmp_randclass rr(gmp_randinit_default);
The first part of your code is seeding the gmp_randstate_t s, but that random state variable s is not used in the second part of your code (after the above change). Unless seeded otherwise, the default GMP random number generator always starts with the same seed, which means the same sequence of random numbers will be generated each time you run the program. You can seed an instance of gmp_randclass using the gmp_randclass::seed function.
The following code is similar to yours but seeds the random number generator based on the current time.
mpz_class ran;
gmp_randclass rr(gmp_randinit_default);
rr.seed(time(NULL));
ran =rr.get_z_bits(125);
long int random=ran.get_ui();
Note that as discussed in Random State Seeding, using a low-resolution current time is usually a poor choice for a random number generator seed.

C++ RNG (Mersenne Twister) needs seed

I have written a RNG class which holds different algorithms, however it does not work as expected. Besides the fact that i want use normal (rather than uniform) distribution my code always returns either the same number (max) or just 2 numbers out of the interval [min,max]:
std::function<int(int, int)> mt19937 =
[](int min, int max) -> int {
std::uniform_int_distribution<int> distribution(min, max);
std::mt19937 engine;
engine.seed(time(null));
auto generator = std::bind(distribution, engine);
return generator();
};
Can anyone explain me what is missing to solve this puzzle? Furthermore, how can i implement normal distribution? Last time i tried out std::normal_distribution i was not able to enter bounds!
EDIT: When i speak of a normal distribution i mean that the results of the RNG near the two bounds should not be generated as often as the mean of both. E.g. look at the graphical representation of the standard Gauss distribution. I am referring to it because it visualizes the probabilities of the resulting values which i want to implement/use this way, if you understand.
The normal distribution is just this (x is a random uniform number):
But I see something that could be problematic:
std::uniform_int_distribution<int> distribution(min, max);
Isn't this giving your number generator an int type?
To fix the seeding problem, create your engine outside of the lambda and seed it when you create it.
A RNG uses an algorithm that produces numbers that appear random, but have a a very large period of repetition (a highlight of the Mersenne Twister). When you seed, you give the RNG an initial value to start the process with. Each time you ask for another number, it spits out another iteration of the algorithm.
When you seed every iteration:
time(NULL)
this code changes only every second, so when you request a new random number, it will only change every second.

C++: seeding random number generator outside of main()

I was creating a simple program that simulates a coin toss for my class. (Actually, class is over this term and i'm just working through the rest of the projects that weren't required). It involves the creating and calling a function that generates a random number between 1 and 2. Originally, I tried to seed the random number generator within the function that would be using it (coinToss); however, it did not produce a random number. Each time the program was run it was the same number as though I had only used
rand()
instead of
unsigned seed = time(0);
srand(seed);
rand();
Yet, when i moved the above within
int main()
it worked fine.
My question is 1)why did it not work when setup within the function that called it and (2) how does rand()
have access to what was done by srand() if they do not both occur in the same function?
Obviously, i'm a beginner so please forgive me if i didn't formulate the question correctly. Also, my book has only briefly touched on rand() and srand() so that's all i really know.
thanks for any help!
Pertinent code:
First attempt that didn't work:
int main()
{
//...........
coinToss();
//...........
}
int coinToss()
{
unsigned seed = time(0);
srand(seed);
return 1 + rand() % 2;
}
Second attempt which did work:
int main()
{
unsigned seed = time(0);
srand(seed);
coinToss();
}
int coinToss()
{
return 1 + rand() % 2;
}
You probably only want to seed the random number generator once. rand() returns the next pseudo-random number from it's internal generator. Every time you call rand() you will get the next number from the internal generator.
srand() however sets the initial conditions of the random number generator. You can think of it as setting the 'starting-out point' for the internal random number generator (in reality it's a lot more complicated than that, but it's a useful cognitive model to follow).
So, you should be calling srand(time(0)) exactly once in your application - somewhere near the beginning. After that, you can call rand() as many times as you want!
However
To answer your actual question - the first version doesn't work because time() returns the number of seconds since the epoch. So If you call coinToss() several times in a second (say, if you wanted to simulate 100 coin tosses), then you'd be constantly seeding the random number generator with the same number, thereby resetting it's internal state (and thus the next number you get) every time.
Anyway - using time() as a seed to srand() is somewhat crappy for this very reason - time() doesn't chage very often, and worse, it's predictable. If you know the current time, you can work out what rand() will return. The internet has many, many examples of better srand() seeds.
Pseudo-random number generators (like rand) work by taking a single starting number (the seed) and performing a numeric transformation on it each time you request a new number. You want to seed the generator just once, or it will continually get reset, which is not what you want.
As you discovered, you should just call srand just once in main. Also note that a number of rand implementations have pretty short cycles on the low 4 bits or so. In practice this means you might get an easily predictable repeating cycle of numbers You might want to shift the return from rand right by 4-8 bits before you take the % 2.
EDIT: The call would look something like:
return 1 + (rand() >> 6) % 2;
Seed only once per program, not every time you call coinToss()
To expand on Mark B's answer: It is not so much that the random number generator is reset as it sets a new variable to be used in calculating random numbers. However your program doesn't do that much work between calls to srand. Therefore every time you call srand(time(0)) it is using the same seed, so you are resetting the internal state of the random number generator . If you put a sleep in there so that time(0) changed you would not get the same number every time.
As for how data passes from srand to rand, it is fairly simple, a global variable is used. All names that start with an underscore and a capital letter or two underscores are reserved for variables used by your compiler. More than likely this variable has been declared static so it isn't visible outside of the translation unit(aka the library file that contains your compiler's standard library.) This is done so that #define STUFF 5 doesn't break your standard library.
for simple simulations, you must not change the seed at all during the simulation. Your simulation will be "worse" in that case.
To understand this, you should see pseudo random sequences as a big wheel of fortune. When you change the seed, it is like you change the position, and then, each call to rand will give you a different number. If you roll again, it will be more probable finding yourself repeating numbers.