I'm trying to find a random number generator that will give me a single random number each time I run it. I have spent a week trying dozens of different ones, both from this site and others. Every time I run it, it gives me the same number! The only time it changes is if I change the range, and then it just gives me the new number over and over.
I am running Code::Blocks ver. 16.01 on Windows 7. Can anyone help?? I'm at my wits' end!
This code gives me a decently ramdom string of numbers, but still the same string each time!
#include <iostream>
#include <random>
int main()
{
std::random_device rd;
std::mt19937 eng(rd()); std::uniform_int_distribution<> distr(0, 10);
for(int n=0; n<100; ++n)
std::cout << distr(eng) << '\t';
}
I have tried the code on my compiler app on my phone as well.
Every pseudo random number generator will return the same sequence of numbers for the same initial seed value.
What you want to do is to use a different seed every time you run the program. Otherwise you'll just be using the same default seed every time and get the same values.
Picking good seeds is not as easy as you might think. Using the output from time(nullptr) for example still gives the same results if two copies of the program run within the same second. Using the value of getpid() is also bad since pid values wrap and thus sometimes you'll get the same value for different runs. Luckily you have other options. std::seed_seq lets you combine multiple bad sources and returns a good (or rather, pretty good) seed value you can use. There is also std::random_device which (on all sane implementations) returns raw entropy - perfect for seeding a pseudo random generator (or you can just use it directly if it is fast enough for your purpose) or you can combine it with std::seed_seq and the bad sources to seed a generator if you are worried it might be implemented as a prng on your implementation.
I would advice you to read this page: http://en.cppreference.com/w/cpp/numeric/random for an overview of how to deal with random number generation in modern C++.
The standard allows std::random_device to be implemented in terms of a pseudo-random number generator if there is no real random source on the system.
You may need to find a different entropy source, such as the time, or user touch co-ordinates.
Related
I have been learning recently how to program games in c++ from a beginner book, and i reached a lesson where i have to make a game in where i have to guess the computer's random picked number, and i have to use this line of code:
srand(static_cast<unsigned int>(time(0)));
variable=rand();
I obviously use iostream cstdlib and ctime.I don't really understand how this works.How is it picking the time and date, and by what rules is it converting into an unsigned int. Basically, how those functions work.
Thank you!
1. About time()
time (or better std::time in C++) is a function that returns some integer or floating point number that represents the current time in some way.
Which arithmetic type it actually returns and how it represents the current time is unspecified, however, most commonly you will get some integer type that holds the seconds since begin of the Unix epoch.
2. About srand()
srand is a function that uses its argument (which is of type unsigned int), the so called seed, to set the internal state of the pseudo number generator rand. When I write random in the rest of this answer, read pseudo random.
Using a different seed will in general result in a different sequence of random numbers produced by subsequent calls to rand, while using the same seed again will result in the exactly same sequence of random numbers.
3. Using time() to seed rand()
If we do not want to get the same random numbers every time we run the program, we need some seed that is different on each run. The current time is a widely used source for such a seed as it changes constantly.
This integer (or whatever else time returned) representing the current time is now converted to unsigned int with a static_cast. This explicit cast is not actually needed as all arithmetic types convert to unsigned int implicitly, but the cast may silence some warnings. As time goes by, we can expect the resulting unsigned int and thus the sequence of random numbers produced by rand to change.
4. Pitfalls
If, as is common, time returns the number of seconds since the beginning of the Unix epoch, there are three important things to note:
The sequence you produce will be different only if at least a second has passed between two invocations.
Depending on the actual implementation, the resulting sequences may start of kind of similar if the time points used to seed rand are close to each other (compared to time since Epoch). Afaik, this is the case in MSVC's implementation. If that is problematic, just discard the first couple of hundred or thousand values of the sequence. (As I have learned by now, this does not really help much for poor RNGs as commonly used for rand. So if that is problematic, use <random> as described below.)
Your numbers are not very random in the end: If someone knows when your call to srand occurred, they can derive the entire sequence of random numbers from that. This has actually led to a decryption tool for a ransom ware that used srand(time(0)) to generate its "random" encryption key.
Also, the sequence generated by rand tends to have poor statistical properties even if the seed was good. For a toy program like yours, that is probably fine, however, for real world use, one should be aware of that.
5. The new <random>
C++11 introduced new random number facilities that are in many ways superior to the old rand based stuff. They provided in the standard header <random>. It includes std::random_device which provides a way to get actually random seeds, powerful pseudo random number generators like std::mt19937 and facilities to map the resulting random sequences to integer or float ranges without introducing unnecessary bias.
Here is an example how to randomly roll a die in C++11:
#include <random>
#include <iostream>
int main()
{
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(1, 6);
for (int n=0; n<10; ++n)
std::cout << dis(gen) << ' ';
std::cout << '\n';
}
(Code from cppr) Note: std::random_device does not work properly with MinGW, at least in the version (Nuwen MinGW5.3) I tested!
It should also be noted that the state space of a mt19937 is much larger than the 32 bit we (commonly) get out of a single call to random_device. Again, this will most likely not matter for toy programs and homework, but for reference: Here is my attempt to properly seed the entire state space, plus some helpful suggestions in the answers.
If you are interested in more details about rand vs <random>, this is an interesting watch.
First line:
srand() is a pseudo-random number generator. In your case it is initialized with the current time (execution time) on your system.
Second line:
After the pseudo-random number generator is configured, you can retrieve random numbers by calling rand().
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.
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.
I have a for loop, and inside it I'm generating random numbers and seeding it with time(msecs),but it's not generatin them randomly, what can I do to solve that?
note:
I know why rand() is not generating them randomly, I'm asking for the solution, and I'm using Qt creator if that will help.
for(int j=0;j<5;j++){
qsrand(QDateTime::currentDateTime().time().msec());//for every j itteratio i must
for(int i=1;i<s;i++){ //have new sequence and ret is
ret.push_back(rand()%s); //vector i'm using Qt
} //s=4 for now,but s=[1;50]
qDebug()<<"new sequence ...";
}
it generates
[2,1,1],[2,1,1],[2,1,1],[2,1,1],[2,1,1];
Depends of what is you application.
If you need to generate secure random numbers that can't be guessed, then you should use CSPRNG https://en.wikipedia.org/wiki/Cryptographically_secure_pseudorandom_number_generator.
For this purpouse there is /dev/urandom availabe for unix clones.
In case you need random numbers for simulation or something similar where you need random numbers you should use high quality super fast, random and large PRNG called mersenne twister.
It is available in standard library of c++11 or in boost. (headers only)
http://en.cppreference.com/w/cpp/numeric/random/mersenne_twister_engine
http://www.boost.org/doc/libs/1_55_0/doc/html/boost_random.html
As many other said, make sure you seed only once.
If you want a long sequence of random numbers, like here, then you probably want to use a pseudo-random number generator (unless this is for cryptography!). C++11 brought support for random and pseudo-random numbers into the standard library, which makes it very easy to use. Just seed the PRNG with a true random number before the loop, then just use the output from that to get (pseudo-)random numbers. You will also need to include the random header.
std::random_device rd;
std::default_random_engine e1{rd()};
std::cout << e1(); // random number
std::cout << e1(); // another random number
std::uniform_int_distribution<> dist{1, 6};
std::cout << dist(e1); // random integer between 1 and 6
If this is for cryptographical uses, see what Luka Rahne said.
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