Random number generator - why seed every time - c++

I am relative new to c and c++. In java, the language I am used to program in, its very easy to implement random number generation. Just call the the static random-method from a class called Math.
int face = ((int)(Math.random() * 6) + 1);
simulates a dice-throw ...
In c and c++ you have to "seed the random number generator" , by calling the srand-function
srand ( time(NULL) );
What is the point of doing this - I mean is there any advantage of having to seed the random number generator every time the code is run?

Given the same seed, a pseudo random number generator will produce the same sequence every time. So it comes down to whether you want a different sequence of pseudo random numbers each time you run, or not.
It really depends on your needs. There are times when you want to repeat a sequence. And times when you do not. You need to understand the needs of each specific application.
One thing you must never do is seed repeatedly during generation of a single sequence. Doing so very likely will destroy the distribution of your sequence.

What's usually called a random number generator is actually a pseudo-random number generator. This typically means that you can generate the same random sequence if you provide the "key" to that sequence, referred to as the "seed". This is very useful when you wish to test your algorithm that is based on randomization, and you need to ensure repeatable results.
If you do not "seed" your Random number generator, it is seeded with some (usually based on system time) random number by default, and therefore produces the different sequence every time that you run your program.

If you don't seed the generator, it will have the same seed every time you run your program, and the random number sequence will be the same each time.
Also note that you only should to seed the generator once, at the beginning of the program.

The advantage is that you can repeat a random number sequence by supplying the same seed.
The game Elite used this to store an entire world, consisting of thousands of stars, as a single number.
To generate the exact same world a second time, the just supplied the same seed.

The seed is needed for pseudo random number generator to generate different random number sequence from previous ones (not always). If you do not want the repeated sequence then you need to seed the pseudo random number generator.
Try these codes and see the difference.
Without seed:
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("%d", rand()%6 + 1);
}
With seed:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
srand(time(NULL));
printf("%d", rand()%6 + 1);
}

The random number generator is not truly random: say you seed it with 12 and make 100 random numbers, repeat the process and seed it with 12 again and make another 100 random numbers, they will be the same.
I have attached a small sample of 2 runs at 20 entries each with the seed of 12 to illustrate, immediately after the code which created them:
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
srand(12);
for (int i =0;i<100; i++)
{
cout << rand() << endl;
}
return 0;
}
To avoid such repetition it is commonplace to use a more unique value, and as the time is always changing, and the chances of a two programs generating random sequences at exactly the same time are slim (especially when at the millisecond level), one can reasonably safely use time as an almost unique seed.
Requirements: seeding only need take place once per unique random sequence you need to generate.
However, there is an unexpected up-/down-side to this:
if the exact time is known of when the first sequence is generated then the exact sequence can be re-generated in the future by entering the seed value manually, causing the random number generator to step through its process in the same fashion as before (this is an upside for storing random sequences, and a downside for preserving their randomness).

In C/C++, a dice roll would be simulated like this:
int face = (rand() % 6) + 1);
^
|___________ Modulo operator
The % 6 limits the random number to 0 through 5 and the + 1 is made to offset the limit, so it becomes 1 through 6.

Related

rand() not giving me a random number (even when srand() is used)

Okay I'm starting to lose my mind. All I want to do is random a number between 0 and 410, and according to this page, my code should do that. And since I want a random number and not a pseudo-random number, I'm using srand() as well, in a way that e.g. this thread told me to do. But this isn't working. All I get is a number that is depending on how long it was since my last execution. If I e.g. execute it again as fast as I can, the number is usually 6 numbers higher than the last number, and if I wait longer, it's higher, etc. When it reaches 410 it goes back to 0 and begins all over again. What am I missing?
Edit: And oh, if I remove the srand(time(NULL)); line I just get the same number (41) every time I run the program. That's not even pseudo random, that's just a static number. Just copying the first line of code from the article I linked to above still gives me number 41 all the time. Am I the star in a sequel to "The Number 23", or have I missed something?
int main(void) {
srand(time(NULL));
int number = rand() % 410;
std::cout << number << std::endl;
system("pause");
}
That is what you get for using deprecated random number generation.
rand produces a fixed sequence of numbers (which by itself is fine), and does that very, very badly.
You tell rand via srand where in the sequence to start. Since your "starting point" (called seed btw) depends on the number of seconds since 1.1.1970 0:00:00 UTC, your output is obviously time depended.
The correct way to do what you want to do is using the C++11 <random> library. In your concrete example, this would look somewhat like this:
std::mt19937 rng (std::random_device{}());
std::uniform_int_distribution<> dist (0, 409);
auto random_number = dist(rng);
For more information on the evils of rand and the advantages of <random> have a look at this.
As a last remark, seeding std::mt19937 like I did above is not quite optimal because the MT's state space is much larger than the 32 bit you get out of a single call to std::random_device{}(). This is not a problem for toy programs and your standard school assignments, but for reference: Here is my take at seeding the MT's entire state space, plus some helpful suggestions in the answers.
From manual:
time() returns the time as the number of seconds since the Epoch,
1970-01-01 00:00:00 +0000 (UTC).
Which means that if you start your program twice both times at the same second you will initialize srand with same value and will get same state of PRNG.
And if you remove initialization via call to srand you will always get exactly same sequence of numbers from rand.
I'm afraid you can't get trully random numbers there. Built in functions are meant to provide just pseudo random numbers. Moreover using srand and rand, because the first uses the same approach as the second one. If you want to cook true random numbers, you must find a correct source of entrophy, working for example with atmospheric noise, as the approach of www.random.org.
The problem here consists in the seed used by the randomness algorithm: if it's a number provided by a machine, it can't be unpredictable. A normal solution for this is using external hardware.
Unfortunately you can't get a real random number from a computer without specific hardware (which is often too slow to be practical).
Therefore you need to make do with a pseudo generator. But you need to use them carefully.
The function rand is designed to return a number between 0 and RAND_MAX in a way that, broadly speaking, satisfies the statistical properties of a uniform distribution. At best you can expect the mean of the drawn numbers to be 0.5 * RAND_MAX and the variance to be RAND_MAX * RAND_MAX / 12.
Typically the implementation of rand is a linear congruential generator which basically means that the returned number is a function of the previous number. That can give surprisingly good results and allows you to seed the generator with a function srand.
But repeated use of srand ruins the statistical properties of the generator, which is what is happening to you: your use of srand is correlated with your system clock time. The behaviour you're observing is completely expected.
What you should do is to only make one call to srand and then draw a sequence of numbers using rand. You cannot easily do this in the way you've set things up. But there are alternatives; you could switch to a random number generator (say mersenne twister) which allows you to draw the (n)th term and you could pass the value of n as a command line argument.
As a final remark, I'd avoid using a modulus when drawing a number. This will create a statistical bias if your modulo is not a multiple of RAND_MAX.
Try by change the NULL in time(NULL) by time(0) (that will give you the current système time). If it doesn't work, you could try to convert time(0) into ms by doing time(0)*1000.

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.

generate 1000 random card deck shuffles at once c++

I'm basically trying to build a computer simulation of a casino game idea that uses a standard deck of 52 cards.
I would like to run 1000 games at once.
I've used srand(time(NULL)) before, but I dont think it's possible to output 1000 different random number sequences at one time with this, is there? My perception is that since all the numbers are generated at the same time, that they will all be the same.
Is there a way to use the first generated random number to seed 1000 new 52 number sequences?
Thanks
Yes, you can have your first random number generator (seeded with time(NULL)) output 1000 random numbers, each of which can be used as a seed for 1000 separate random number generators.
My perception is that since all the numbers are generated at the same
time, that they will all be the same
They are not generated at the same time. I presume you are using a for loop? Each iteration is not
at the same time".
Did you even test this theory?
for i = 1 to 1000 do
{
print <time to ms resolution>
print <random number>
}
Seeding with the same number will always lead to the same sequence of pseudo-random numbers. As long as you don't re-seed with the same seed in between iterations, the (sub)sequences are not going to be the same.
try seeding the rand() function with srand(time(NULL)*getpid()). PID of the process that you are invoking a 1000 times should be system dependent and has a good chance of being different from one another.
If you are using threads for different games, use threadID instead of getpid().
If you want you can pre-generate all random numbers at once and use them later:
int random_numbers[1000];
for (i = 0; i < 1000; i++) {
srand(time(NULL)*(i+1));
random_numbers[i] = rand();
}

Same random numbers every time I run the program

My random numbers that output, output in the same sequence every time I run my game. Why is this happening?
I have
#include <cstdlib>
and am using this to generate the random numbers
randomDiceRollComputer = 1 + rand() % 6;
You need to seed your random number generator:
Try putting this at the beginning of the program:
srand ( time(NULL) );
Note that you will need to #include <ctime>.
The idea here is to seed the RNG with a different number each time you launch the program. By using time as the seed, you get a different number each time you launch the program.
You need to give the randum number generator a seed. This can be done by taking the current time, as this is hopefully some kind of random.
#include <cstdlib>
#include <ctime>
using namespace std;
int main()
{
int r;
srand(time(0));
r = rand();
return 0;
}
The rand() function is specifically required to produce the same sequence of numbers when seeded with a given seed (by calling srand()); each possible seed value specifies a sequence. And if you never call srand(), you get the same sequence you would have gotten by calling srand(1) before any call to rand().
(This doesn't apply across different C or C++ implementations.)
This can be useful for testing purposes. If there's a bug in your program, for example, you can reproduce it by re-running it with the same seed, guaranteeing that (barring other unpredictable behaviors) you'll get the same sequence of pseudo-random numbers.
Calling srand(time(NULL)) is the usual recommended way to get more or less unpredictable pseudo-random numbers. But it's not perfect. If your program runs twice within the same second, you'll probably get the same sequence, because time() (typically) has a resolution of 1 second. And typical `rand() implementations are not good enough for cryptographic use; it's too easy for an attacker to guess what numbers you're going to get.
There are a number of other random number implementations. Linux systems have two pseudo-devices, /dev/random and /dev/urandom, from which you can read reasonably high-quality pseudo-random byte values. Some systems might have functions like random(), drand48(), and so forth. And there are numerous algorithms; I've heard good things about the Mersenne Twister.
For something like a game, where you don't expect or care about players trying to cheat, srand(time(NULL)) and rand() is probably good enough. For more serious purposes, you should get advice from someone who knows more about this stuff than I do.
Section 13 of the comp.lang.c FAQ has some very good information about pseudo-random number generation.
Pseudorandom number generators take a starting number, or seed, and then generate the next number in the sequence from this. That's why they're called pseudorandom, because if they always use the same starting value, they will generate the same sequence of numbers like the C standard lib generator does. This can be fixed by giving the generator a starting value that will change the next time the program is run like the current time.
Anyway, the code you're looking for like others have said is:
srand(time(0)); //Seed the generator, give it a starting value

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.