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.
Related
I have a member function of a class that is supposed to generate a random number in a range. To do so, I am using the rand() function. The function generates a random number like this:
unsigned seed;
seed = time(0);
srand(seed);
std::cout << "Random Number: "<< rand() << std::endl;
The function is called on two different objects. The result is:
Random Number: 1321638448
Random Number: 1321638448
This is consistent every-time I call it. What am i doing wrong?
(Converting my comment to an answer).
For most applications, you'll only really want to seed rand once in the course of running a program. Seeding it multiple times requires you to get different random seeds, and it's easy to mess that up.
In your case, the time function usually returns something with resolution on the level of seconds (though this isn't actually required by the standard). As a result, if you call time twice within the same second, you might get back the same value. That would explain why you're getting duplicate values: you're seeding the randomizer with the same value twice and then immediately querying it for a random number.
The best solution to this is to just seed the randomizer once. Typically, you'd do that in main.
If you really do want to seed the randomizer multiple times, make sure that you're doing so using a seed that is going to be pretty much random. Otherwise, you risk something like this happening.
Pseudorandom number generators basically have to pass a set of statistical tests to make sure they're "random enough" as a set of numbers. But of course, it's not actually random. Calling srand(seed) with some seed basically generates a set of numbers which, if passed through those tests, will seem "random enough".
By calling srand(seed) with the same seed multiple times, you're effectively generating the same set over and over again and getting the first value in it.
You call srand(seed) ONCE, and then you call rand() to get the next values in the random number set. Or you need to call srand(seed) with a different (random) seed each time.
If you're on linux, you can also use /dev/urandom to get a random number- the kernel has been taking signal/noise from the environment to generate "entropy" for it, supposedly making it even better than an algorithm psuedorandom number generator.
srand function should be called only once in program(most cases, not all cases). If you want reseed, you should use different seed number. Because rand() function is pseudo-random number generator. In other words, rand() gives you a calculated number.
You can use much for powerful random number generating library after C++11. See: http://en.cppreference.com/w/cpp/numeric/random
Question
Is it possible to seed the mt19937_64 engine in such a way that the same sequence is generated each time a program is run?
I presume this is possible, as there is a seed function. However I don't know if this will do what I want it to, or will work as I expect, generating the same sequence each time.
You can either set the seed using seed or call the constructor that takes a seed. In either case ensure you are passing some constant such as 27423.
my rand number is rand()%6+1 aka dice rolling, when its based on "time", is it possible to make a console app that foresees the future numbers in the time I want to? for example predict a number on time 14:40:32 on a certain day in future?
Yes provided that you use the same implementation of rand i.e. link with the same version of the standard library. All you need is to get the time_t value for the time you are interested in pass it to srand and call rand to get the value.
For example, if time_t holds the number of seconds since the epoch (which is the case for most implementations), then you can do the following to get the value returned by rand with a 10-second-in-the-future seed:
std::srand(std::time(nullptr) + 10);
std::cout << std::rand();
(Leaving aside the questions of whether it's a good idea to use rand at all.)
... for example predict a number on time 14:40:32 on a certain day in future?
It's possible when knowing how exactly rand() generates the pseudo random number on a certain seed (which is available for most compilers open source code implementation).
You have a certain seed number given from your date and time, thus you can just inspect the sequence of random numbers generated consecutively.
Yes and no. If you have a value of time_t, then just run the same library version of srand() on that value, and rand() will definitely yield the same sequence.
But you need to be sure that
the random libraries in the two applications use the same implementation (I think it's Mersenne Twister, but I'd need to check)
the clock of the two applications is synchronised. If you think that the master application's clock is 14:30:17, but it's really 14:30:18, then entering 14:30:17 in the monitor application will (of course) get different values.
the sequence of calls to rand() in both applications is the same, i.e., the number of calls between the srand() and the rand() you are interested in is known by you.
The last point might be a showstopper.
Say that you know that the app was initialised with srand(T) and you know T. Now yes, you know all the future extractions of its rand(). But you still need to know at which point in the sequence you are.
The number extracted at 19:30:17 GMT will not depend on the '19:30:17 GMT', but on how many numbers have been extracted before since the call to srand().
TL;DR if you know the value that time(0) passed to srand(), you cannot predict the output of the rand() call at a given time. You can predict the output of the n-th call to rand() for any given n.
my rand number is rand()%6+1 aka dice rolling, when its based on "time", is it possible to make a console app that foresees the future numbers in the time I want to? for example predict a number on time 14:40:32 on a certain day in future?
Yes provided that you use the same implementation of rand i.e. link with the same version of the standard library. All you need is to get the time_t value for the time you are interested in pass it to srand and call rand to get the value.
For example, if time_t holds the number of seconds since the epoch (which is the case for most implementations), then you can do the following to get the value returned by rand with a 10-second-in-the-future seed:
std::srand(std::time(nullptr) + 10);
std::cout << std::rand();
(Leaving aside the questions of whether it's a good idea to use rand at all.)
... for example predict a number on time 14:40:32 on a certain day in future?
It's possible when knowing how exactly rand() generates the pseudo random number on a certain seed (which is available for most compilers open source code implementation).
You have a certain seed number given from your date and time, thus you can just inspect the sequence of random numbers generated consecutively.
Yes and no. If you have a value of time_t, then just run the same library version of srand() on that value, and rand() will definitely yield the same sequence.
But you need to be sure that
the random libraries in the two applications use the same implementation (I think it's Mersenne Twister, but I'd need to check)
the clock of the two applications is synchronised. If you think that the master application's clock is 14:30:17, but it's really 14:30:18, then entering 14:30:17 in the monitor application will (of course) get different values.
the sequence of calls to rand() in both applications is the same, i.e., the number of calls between the srand() and the rand() you are interested in is known by you.
The last point might be a showstopper.
Say that you know that the app was initialised with srand(T) and you know T. Now yes, you know all the future extractions of its rand(). But you still need to know at which point in the sequence you are.
The number extracted at 19:30:17 GMT will not depend on the '19:30:17 GMT', but on how many numbers have been extracted before since the call to srand().
TL;DR if you know the value that time(0) passed to srand(), you cannot predict the output of the rand() call at a given time. You can predict the output of the n-th call to rand() for any given n.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 9 years ago.
Improve this question
why is it when i call srand() at 2 very different points it cause numbers to not be random? Once i remove one of them it goes back to normal.
It depends on how you call it. The purpose of srand() is to seed the pseudo-random number generator used by rand(). So when you call srand(i), it will initialise rand() to a fixed sequence which depends on i. So when you re-seed with the same seed, you start getting the same sequence.
The most common use case is to seed the generator just once, and with a suitable "random" value (such as the idiomatic time(NULL)). This guarantees makes it likely that you'll get different sequences of pseudo-random numbers in different program executions.
However, occasionally you might want to make the pseudo-random sequence "replayable." Imagine you're testing several sorting algorithms on random data. To get fair comparisons, you should test each algorithm on the exact same data - so you'll re-seed the generator with the same seed before each run.
In other words: if you want the numbers simply pseudo-random, seed once, and with a value as random as possible. If you want some control & replayability, seed as necessary.
srand (seed);
Two different initializations with the same seed will generate the
same succession of results in subsequent calls to rand.
If seed is set to 1, the generator is reinitialized to its initial
value and produces the same values as before any call to rand or
srand.
Each time rand() is seeded with srand(), it must produce the same
sequence of values.
http://www.cplusplus.com/reference/cstdlib/srand/
http://en.cppreference.com/w/cpp/numeric/random/srand
Are you initializing the srand? You have to initialize it in the beginning of you function/code like this:
srand(time(NULL));
It should work :)
You may read about pseudo random numbers generators, standard library srand-rand functions are implementation of one of them.
The core idea is that pseudo random generator is initialized with the special number - seed.
srand() is used to set seed. For every seed pseudo random generator generate exactly the same sequence of numbers ever. By using different seeds you'll get different sequences of numbers.
So if you want to get different random numbers everytime you start you program, you need everytime to set new seed.
The one of simpliest way to do this is to use time for seed.
#include <time.h>
srand((unsigned int)time(0));