This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
rand function returns same values when called within a single function c++
I have a program which creates a new set of random numbers each mouse click. If I run the program without srand ( time(NULL) ); the numbers are the same each time. If I run the program WITH srand ( time(NULL) ); then it's possible for me to spam click and the numbers will repeat themselves. How can I get around this?
Your problem is about seeding the random number generator with the same value. The srand function is for initializing the so called "seed" for it. A seed can be used to generate the same random numbers in a sequence.
First you need to initialize the generator then just call the rand function without arguments, and it will generate random numbers. For example:
/* initialize random seed with actual date-time */
std::srand(std::time(NULL));
/* generate ten random number lower than 10 */
int random, times = 10;
while(times){
random = std::rand() % 10;
times--;
}
About the "spam click": std::time(NULL) has precision in seconds, so you're initializing the random seed with the same value if you click within the same second.
Here is an example on the official c++ reference site,
and another example on cplusplus.com too.
rand function is not very good at generating random numbers, take a look at boost::random. it is awesome and can create random and semi random numbers
Related
This question already has answers here:
Why does rand() yield the same sequence of numbers on every run?
(7 answers)
Closed 3 years ago.
So I am new to C++ and learning all alone... until now everything went fine, but i am learning how to use rand() and the result does bother me a little...
So my goal is to generate a random number for the HP of a player at the beginning of a game. To be fair, I set up a minimal HP of 50 points and I want to create a random number with 50 being the minimal and 200 the maximum.
int HP = 50 + rand() %200;
cout << HP;
Now, the problem is:
The program always give me the same int.
To check the result i created a new project and only displayed the rand() number with the same values, and I got the same result -> 91.
this mean, I would say int HP = 91; would be exactly the same.
Practice and trial being the key to learn (I think) I tried the same rand() values on 5 new projects, always the same number...
std::srand() seeds the pseudo-random number generator used by rand(). If rand() is used before any calls to srand(), rand() behaves as if it was seeded with srand(1).
Each time rand() is seeded with srand(), it must produce the same sequence of values on successive calls.
https://en.cppreference.com/w/cpp/numeric/random/rand
Therefore, what you're seeing is (awkardly) exactly what rand is supposed to do. The easy fix is to call std::srand(std::time(nullptr)); so that each time the program runs, it starts with a different seed.
The more advanced fix is to study The awesome C++ standard randum number library
std::default_random_engine e1(r());
std::uniform_int_distribution<int> uniform_dist(50, 250);
int HP = uniform_dist(e1);
rand() isn't really the best random number generator, but if you're going to use it you need to seed it with the srand function as follows:
srand(time(0));
This question already has answers here:
Random seed at runtime
(3 answers)
Closed 7 years ago.
In my program, I have a function return_random_vector() which takes a set of numbers, say 1,2,3,4,5, and returns a random rearrangement of the numbers such as 2,5,1,4,3.
In order to do this, I set the seed srand(time(NULL)). For my program, I want to be able to call this function again with 1,2,3,4,5 and get another rearrangement of them, for example 3,1,4,5,2.
Is there a way I can set srand() so that the seed can be reset?
To get a different set, you can call return_random_vector() again without calling srand() in between.
Calling srand((unsigned)time(NULL)) right after the first call to return_random_vector() will likely generate the same set because time() will probably return the same value, which is the elapsed time in seconds.
So you would in fact be resetting the seed to the same value as it was before the first call. And setting the seed to the same value will generate the same set of random numbers again.
You could also take a look at std::shuffle (C++11).
Every time you call srand() with a different value, you initialize the random number generator to return a different sequence of values.
Just call srand() again in the same way. Since the time value will likely be different, you will get a different sequence of results from rand().
If it is possible you need to do this before the time() value has changed, you can use:
srand(time(NULL)+rand());
It's a while since I last wrote C++, so I'm not sure if you'll need to cast one or the other values before doing the addition, being that they're an int and a time_t.
For *nix system, you can try this one
unsigned seed;
read(open("/dev/urandom", O_RDONLY), &seed, sizeof(seed));
srand(seed);
For Windows, RtlGenRandom will give you an array of random bytes, which can be used as seed. Or just be used as a pseudo-random number.
This question already has answers here:
What does 'seeding' mean?
(4 answers)
Closed 6 years ago.
What is a seed in terms of generating a random number?
I need to generate hundreds to thousands of random numbers, I have read a lot about using a "seed". What is a seed? Is a seed where the random numbers start from? For example if I set my seed to be 5 will it generate numbers from 5 to whatever my limit is? So it will never give me 3 for example.
I am using C++, so if you provide any examples it'd be nice if it was in C++.
Thanks!
What is normally called a random number sequence in reality is a "pseudo-random" number sequence because the values are computed using a deterministic algorithm and probability plays no real role.
The "seed" is a starting point for the sequence and the guarantee is that if you start from the same seed you will get the same sequence of numbers. This is very useful for example for debugging (when you are looking for an error in a program you need to be able to reproduce the problem and study it, a non-deterministic program would be much harder to debug because every run would be different).
If you need just a random sequence of numbers and don't need to reproduce it then simply use current time as seed... for example with:
srand(time(NULL));
So, let's put it this way:
if you and your friend set the seed equals to the same number, by then you and your friend will get the same random numbers. So, if all of us write this simple program:
#include<iostream>
using namespace std;
void main () {
srand(0);
for (int i=0; i<3; i++){
int x = rand()%11; //range between 0 and 10
cout<<x<<endl;
}
}
We all will get the same random numbers which are (5, 8, 8).
And if you want to get different number each time, you can use srand(time())
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.
This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
What’s the Right Way to use the rand() Function in C++?
When I run the below program I always get the same values each time. Is rand not a true random function?
int main()
{
while(1)
{
getch();
cout<<rand()<<endl;
}
}
In each run I am getting the below values.
41
18467
6334
26500
19169
15724
......
Yes and no. rand() is a pseudo random number generator that will always return the same sequence of numbers given the same seed value. Typically one 'seeds' the random number generator with some random data and then uses rand() to return a sequence of seemingly random numbers. If your random data isn't needed for something requiring 'true' randomness (such as cryptography based security) just using the current system time is sufficient. However, if you are using it for security purposes, look into obtaining more truly random data from entropy gathering utilities and use that to seed the random number generator.
As aa mentioned, the seed function is referenced here
What is a true random function? Last I checked, computers couldn't do that :)
As to why you are getting the same set of numbers each time, it's because you need to seed the built in number generator with some starting 'random' value. There are many places to get this, but some tend to look good, but turn out bad. In our games, we generally seed with tic time from game bootup until the first or second user input. User input will always vary across many tics and can therefore be used as a decent starting point.
If you are using a Microsoft compiler, you can use rand_s, which generates very good random numbers (as good as you can get with only a computer): http://msdn.microsoft.com/en-us/library/sxtz2fa8%28VS.80%29.aspx
You can also use /dev/urandom on Linux and CryptGenRandom() on Windows to get quality random numbers.
or put srand() at the beginning of the function.
Just to follow on from the disucussion on "True" random numbers. As already, stated any generator that has a seed has a predictable period - I believe it can be 2^48.
If that level of randomness you can use the following:
long randomLong(unsigned int x)
{
x ^= (x << 21); // x is a non zero seed value
x ^= (x >> 35);
x ^= (x << 4);
return x;
}
This is taken from the following paper:
http://www.jstatsoft.org/v08/i14/paper
Which is a really interesting paper describing some low cost random number generators