I have the following code:
Class B {
void generator()
{
// creating random number generator
boost::mt19937 randgen(static_cast<unsigned int>(std::time(0)));
boost::normal_distribution<float> noise(0,1);
boost::variate_generator<boost::mt19937,
boost::normal_distribution<float> > nD(randgen, noise);
for (int i = 0; i < 100; i++)
{
value = nD();
// graph each value
}
}
};
Class A {
void someFunction()
{
for(int i = 1; i <=3; i++)
{
std::shared_ptr<B> b;
b.reset(new B());
b->generator();
}
}
};
I wish to execute the above code multiple times in rapid succession to produce multiple graphs. I have also reviewed this stackoverflow question which is similar but the caveat states that when time(0) is used and the member function is called in rapid succession then you will still likely get the same sequence of numbers.
How might I overcome this problem?
EDIT: I've tried making randgen static in Class B, also tried making it a global variable in Class A, but each time the 3 graphs are still the same. I've also tried seeding from the GetSystemTime milliseconds. I must be missing something.
One way would be to not reseed the random number generator every time you execute your code.
Create the generator and seed it once, then just continue to use it.
That's assuming you're calling that code multiple times within the same run. If you're doing multiple runs (but still within the same second), you can use another differing property such as the process ID to change the seed.
Alternatively, you can go platform-dependent, using either the Windows GetSystemTime() returning a SYSTEMTIME structure with one of its elements being milliseconds, or the Linux getTimeOfDay returning number of microseconds since the epoch.
Windows:
#include <windows.h>
SYSTEMTIME st;
GetSystemTime (&st);
// Use st.wSecond * 100 + st.wMillisecs to seed (0 thru 59999).
Linux:
#include <sys/time.h>
struct timeval tv;
gettimeofday (&tv, NULL);
// Use tv.tv_sec * 100 + (tv.tv_usec / 1000) to seed (0 thru 59999).
With Boost.Random you can save the state of the random number generator--for example, you can save it to a text file. This is done with streams.
For example, using your code, after you seed the generator and have run it once, you can save the state with an output stream, like so:
std::ofstream generator_state_file("rng.saved");
generator_state_file << randgen;
Then later, when you've created a new generator, you can load the state back from that file using the opposite stream:
std::ifstream generator_state_file("rng.saved");
generator_state_file >> randgen;
And then use the state to generate some more random numbers, and then re-save the state, and so on and so on.
It may also be possible to save the state to a std::string using std::stringstream, if you don't want to use a file, but I haven't personally tried this.
Only create a single random number generator so it's only seeded once:
static boost::mt19937 randgen(static_cast<unsigned int>(std::time(0)));
First Thoughts
On unix you could try reading some bytes from /dev/random or /dev/urandom for the seed. You could also try using a combination of time(0) + pid + static counter (or pseudo-random sequence).
I believe on windows, you can use QueryPerformanceCounter to get the value of the high performance timer register.
Another thought:
You could declare your mt19937 prng as a static or global so you never lose its state.
A third thought:
You wish to "execute the above code multiple times in rapid succession to produce multiple graphs" pass in a graph index. (e.g. genGraph(int graphIndex) and combine this (add, xor, etc) with the output of time(0). boost::mt19937 randgen(static_cast<unsigned int>(std::time(0) + graphIndex));
A late answer: two random-number generator functions for comparing boost with standard method.
boost
#include <boost/random.hpp>
//the code that uses boost is massively non-intuitive, complex and obfuscated
bool _boost_seeded_=false;
/*--------------------*/int
boostrand(int High, int Low)
{
static boost::mt19937 random;
if (!_boost_seeded_)
{
random = boost::mt19937(time(0));
_boost_seeded_=true;
}
boost::uniform_int<> range(Low,High);
boost::variate_generator<boost::mt19937&, boost::uniform_int<> >
getrandom(random, range);
return getrandom();
}
standard
#include <cstdlib>
#include <time.h>
//standard code is straight-forward and quite understandable
bool _stdrand_seeded_=false;
/*--------------------*/int
stdrand(int High, int Low)
{
if (!_stdrand_seeded_)
{
srand(time(0));
_stdrand_seeded_=true;
}
return ((rand() % (High - Low + 1)) + Low);
}
The results from both functions are comparably of the same "randomness". I would apply the KISS-principle.
If you do not want to use only one generator you could create one generator with seed(time(0)) and then use that generator as seed into the other generators.
time(0) has the resolution of 1 second. Using it multiple times as seed within a short time span will create the same generator.
Related
So in c++ I'm using mt19937 engine and the uniform_int_distribution in my random number generator like so:
#include <random>
#include <time.h>
int get_random(int lwr_lm, int upper_lm){
std::mt19937 mt(time(nullptr));
std::uniform_int_distribution<int> dist(lwr_lm, upper_lm);
return dist(mt);
}
What I need is to alter the above generator such that there is a cache that contains a number of integers I need to be excluded when I use the above generator over and over again.
How do I alter the above such that I can achieve this?
There are many ways to do it. A simple way would be to maintain your "excluded numbers" in a std::set and after each generation of a random number, check whether it is in the set and if it is then generate a new random number - repeat until you get a number that was not in the set, then return that.
Btw; while distributions are cheap to construct, engines are not. You don't want to re-construct your mt19937 every time the function is called, but instead create it once and then re-use it. You probably also want to use a better seed than the current time in seconds.
Are you 1) attempting to sample without replacement in the discrete interval? Or is it 2) a patchy distribution over the interval that says fairly constant?
If 1) you could use std::shuffle as per the answer here How to sample without replacement using c++ uniform_int_distribution
If 2) you could use std::discrete_distribution (element 0 corresponding to lwr_lm) and weight zero the numbers you don't want. Obviously the memory requirements are linear in upper_lm-lwr_lm so might not be practical if this is large
I would propose two similar solutions for the problem. They are based upon probabilistic structures, and provide you with the answer "potentially in cache" or "definitely not in cache". There are false positives but no false negatives.
Perfect hash function. There are many implementations, including one from GNU. Basically, run it on set of cache values, and use generated perfect hash functions to reject sampled values. You don't even need to maintain hash table, just function mapping random value to integer index. As soon as index is in the hash range, reject the number. Being perfect means you need only one call to check and result will tell you that number is in the set. There are potential collisions, so false positives are possible.
Bloom filter. Same idea, build filter with whatever bits per cache item you're willing to spare, and with quick check you either will get "possible in the cache" answer or clear negative. You could trade answer precision for memory and vice versa. False positives are possible
As mentioned by #virgesmith, in his answer, it might be better solution in function of your problem.
The method with a cache and uses it to filter future generation is inefficient for large range wiki.
Here I write a naive example with a different method, but you will be limited by your memory. You pick random number for a buffer and remove it for next iteration.
#include <random>
#include <time.h>
#include <iostream>
int get_random(int lwr_lm, int upper_lm, std::vector<int> &buff, std::mt19937 &mt){
if (buff.size() > 0) {
std::uniform_int_distribution<int> dist(0, buff.size()-1);
int tmp_index = dist(mt);
int tmp_value = buff[tmp_index];
buff.erase(buff.begin() + tmp_index);
return tmp_value;
} else {
return 0;
}
}
int main() {
// lower and upper limit for random distribution
int lower = 0;
int upper = 10;
// Random generator
std::mt19937 mt(time(nullptr));
// Buffer to filter and avoid duplication, Buffer contain all integer between lower and uper limit
std::vector<int> my_buffer(upper-lower);
std::iota(my_buffer.begin(), my_buffer.end(), lower);
for (int i = 0; i < 20; ++i) {
std::cout << get_random(lower, upper, my_buffer, mt) << std::endl;
}
return 0;
}
Edit: a cleaner solution here
It might not be the prettiest solution, but what's stopping you from maintaining that cache and checking existence before returning? It will slow down for large caches though.
#include <random>
#include <time.h>
#include <set>
std::set<int> cache;
int get_random(int lwr_lm, int upper_lm){
std::mt19937 mt(time(nullptr));
std::uniform_int_distribution<int> dist(lwr_lm, upper_lm);
auto r = dist(mt);
while(cache.find(r) != cache.end())
r = dist(mt);
return r;
}
A neuroevolution program I am in the process of debugging does not produce random values every time it is called. In the program, a vector of Network objects are initialized with the following statement:
vector<Network> population(POPULATION_SIZE, Network(sizes, inputCount));
Why I believe the program not to be converging to an optimal solution is that, always, the first 100 of the population are the same. When a network is initialized in this manner, the connection weights and neuron biases are (each) initialized with the following class function:
double Network::randDouble(double low, double high) {
/*default_random_engine generator(std::chrono::system_clock::now().time_since_epoch().count());
uniform_real_distribution<double> distribution(low, high);
return distribution(generator);*/
/*srand(time(NULL));
double temp;
if (low > high) {
temp = low;
low = high;
high = temp;
}
temp = (rand() / (static_cast<double>(RAND_MAX) + 1.0)) * (high - low) + low;
return temp;*/
/*mt19937 rgn(std::chrono::system_clock::now().time_since_epoch().count());
uniform_real_distribution<double> gen(low, high);
return gen(rgn);*/
default_random_engine rd;
uniform_real_distribution<double> gen(low, high);
auto val = std::bind(gen, rd);
return val();
}
The 3 commented-out sections are previously attempted means of generating the functionality required. In each case, they produce the same numbers for each network (differing from 1 weight to another, but not 1 network to another). The methods attempted are based on answers from here:
c++-default_random_engine creates all the time same series of numbers
http://en.cppreference.com/w/cpp/numeric/random/uniform_real_distribution
In addition, the second method produces the same results with or without the seed. I must be missing something.
Another, albeit potentially irrelevant concern, is that functions using this may be parallel-ized using OpenMP, and that when called in parallel, the results could be the same.
Your problem is that you are initializing (seeding) the random generator every time you generate a number. In the simple srand() case, you should call srand() just once during program start, then call rand() every time you need one number. In the more complex cases, you should construct the generator just once (in the entire program run), and use it as many times as you need.
The C++11 standard random-number engines (and most other random generators) are in fact generators of pseudo-random sequences of numbers. Pseudo-random means that the sequences are repeatable. Every time a given pseudo-random generator is seeded with the same seed, it will always produce the same sequence. (But this is not exactly what is happening in your code. Read on.)
In C++11, the seeding happens at the time the random-number engine is instantiated. This means that you need to instantiate the engine once per pseudorandom sequence. The way your code seeds the engine in every call to the Network::randDouble() method, you cannot expect to get the pseudorandom sequence that the engine is designed to produce. Instead, you will get a series of the first numbers from sequences seeded by the call to the system_clock::... or the time() methods.
The call to the system_clock::now().time_since_epoch().count() returns time in integer number of periods. The period refers to the specialization of the template class std::chrono::duration which is returned by time_since_epoch(). The period may be seconds by default, which could explain why all your Network objects were getting the same seed in every call to Network::randDouble().
If you want a different sequence for each of the Networks, you should better instantiate the pseudorandom engine in the c-tor of the Network class, and seed it with a different seed for each object of the Network class. This means that the engine, or a pointer to the engine object should be member of the class.
Example:
class Network {
...
protected:
mt19937 rd;
...
}
Network::Network(int rndseed) :
rd(rndseed)
{
...
}
double Network::randDouble(double low, double high) {
uniform_real_distribution<double> gen(low, high);
auto val = gen(rd);
return val;
}
To make sure that each instance of the pseudorandom engine is getting a different seed, you may use something as simple as consequent integer numbers. If you want to use the system clock, it is far more tricky to guarantee that the seeds are different every time, even if you use std::chrono::high_resolution_clock. CPUs are simply very fast and you need to take special care to make sure that the count of the clock that you are using has actually changed between two calls.
My program needs to generate many random integers in some range (int min, int max). Each call will have a different range. What is a good (preferably thread-safe) way to do this? The following is not thread-safe (and uses rand(), which people seem to discourage):
int intRand(const int & min, const int & max)
{
return (rand() % (max+1-min)) + min;
}
This is much slower, but uses <random>:
int intRand(const int & min, const int & max) {
std::default_random_engine generator;
std::uniform_int_distribution<int> distribution(min,max);
return distribution(generator);
}
Something like this is what I'm going for (the changeParameters function doesn't exist though):
int intRand(const int & min, const int & max) {
static std::default_random_engine generator;
static std::uniform_int_distribution<int> distribution(0, 10);
distribution.changeParameters(min, max);
return distribution(generator);
}
Another option would be to make a wide range on the uniform_int_distribution and then use mod like in the first example. However, I'm doing statistical work, so I want the numbers to come from as unbiased of a distribution as possible (e.g., if the range of the distribution used is not a multiple of (max-min), the distribution will be slightly biased). This is an option, but again, I would like to avoid it.
SOLUTION This solution comes from the answers by #konrad-rudolph #mark-ransom and #mathk . The seeding of the random number generator is done to suit my particular needs. A more common approach would be to use time(NULL). If you make many threads in the same second, they would then get the same seed though. Even with clock() this is an issue, so we include the thread id. A drawback - this leaks memory --- one generator per thread.
#if defined (_MSC_VER) // Visual studio
#define thread_local __declspec( thread )
#elif defined (__GCC__) // GCC
#define thread_local __thread
#endif
#include <random>
#include <time.h>
#include <thread>
using namespace std;
/* Thread-safe function that returns a random number between min and max (inclusive).
This function takes ~142% the time that calling rand() would take. For this extra
cost you get a better uniform distribution and thread-safety. */
int intRand(const int & min, const int & max) {
static thread_local mt19937* generator = nullptr;
if (!generator) generator = new mt19937(clock() + this_thread::get_id().hash());
uniform_int_distribution<int> distribution(min, max);
return distribution(*generator);
}
Have you tried this?
int intRand(const int & min, const int & max) {
static thread_local std::mt19937 generator;
std::uniform_int_distribution<int> distribution(min,max);
return distribution(generator);
}
Distributions are extremely cheap (they will be completely inlined by the optimiser so that the only remaining overhead is the actual random number rescaling). Don’t be afraid to regenerate them as often as you need – in fact, resetting them would conceptually be no cheaper (which is why that operation doesn’t exist).
The actual random number generator, on the other hand, is a heavy-weight object carrying a lot of state and requiring quite some time to be constructed, so that should only be initialised once per thread (or even across threads, but then you’d need to synchronise access which is more costly in the long run).
Make the generator static, so it's only created once. This is more efficient, since good generators typically have a large internal state; more importantly, it means you are actually getting the pseudo-random sequence it generates, not the (much less random) initial values of separate sequences.
Create a new distribution each time; these are typically lightweight objects with little state, especially one as simple as uniform_int_distribution.
For thread safety, options are to make the generator thread_local, with a different seed for each thread, or to guard it with a mutex. The former is likely to be faster, especially if there's a lot of contention, but will consume more memory.
You can use one default_random_engine per thread using Thread Local Storage.
I can not tell you how to correctly use TLS since it is OS dependent. The best source you can use is to search through the internet.
I am a person from the future with the same problem. The accepted answer won't compile on MSVC 2013, because it doesn't implement thread_local (and using __declspec(thread) doesn't work because it doesn't like constructors).
The memory leak in your solution can be moved off the heap by modifying everything to use placement new.
Here's my solution (combined from a header and source file):
#ifndef BUILD_COMPILER_MSVC
thread_local std::mt19937 _generator;
#else
__declspec(thread) char _generator_backing[sizeof(std::mt19937)];
__declspec(thread) std::mt19937* _generator;
#endif
template <typename type_float> inline type_float get_uniform(void) {
std::uniform_real_distribution<type_float> distribution;
#ifdef BUILD_COMPILER_MSVC
static __declspec(thread) bool inited = false;
if (!inited) {
_generator = new(_generator_backing) std::mt19937();
inited = true;
}
return distribution(*_generator);
#else
return distribution(_generator);
#endif
}
Write a simple LCG (or whatever) PRNG for yourself, which will produce numbers up to the maximum possible required. Use a single static copy of the built-in RNG to seed a new local copy of your own PRNG for each new thread you generate. Each thread-local PRNG will have its own local storage, and never needs to refer to the central RNG again.
This assumes that a statistically good RNG is fine for you and that cryptographic security is not an issue.
I am having trouble with rand_r. I have a simulation that generates millions of random numbers. I have noticed that at a certain point in time, these numbers are no longer uniform. What could be the problem?
What i do: i create an instance of a generator and give it is own seed.
mainRGen= new nativeRandRUni(idumSeed_g);
here is the class/object def:
class nativeRandRUni {
public:
unsigned seed;
nativeRandRUni(unsigned sd){ seed= sd; }
float genP() { return (rand_r(&seed))/float(RAND_MAX); } // [0,1]
int genI(int R) { return (rand_r(&seed) % R); } // [0,R-1]
};
numbers are simply generated by:
newIntNumber= mainRGen->genI(desired_max);
newFloatNumber= mainRGen->genP();
the simulations have the problem described above. I know this is happening cause i have checked the distribution of the generated numbers after the point in time that a signature is shown in the results (see this, top image, http://ubuntuone.com/0tbfidZaXfGNTfiVr3x7DR)
also, if i print the seed at t-1 and t, being t the time point of the signature, i can see the seed changing by an order of magnitude from value 263069042 to 1069048066
if i run the code with a different seed, the problem is always present but at different time points
Also, if i use rand() instead of my object, all goes well... i DO need the object cause sometimes i used threads. The example above does not have threads.
i am really lost here, any clues?
EDIT - EDIT
it can be reproducible by looping enough times, problem is that, like i said, it takes millions of iterations for the problem to arise. For seed -158342163 i get it at generation t=134065568. One can check numbers generated before (uniform) and after (not uniform). I get the same problem if i change the seed manually at given t's, see (*) in code. Something i also do not expect to happen?
#include <tr1/random>
#include <fstream>
#include <sstream>
#include <iostream>
using std::ofstream;
using std::cout;
using std::endl;
class nativeRandRUni {
public:
unsigned seed;
long count;
nativeRandRUni(unsigned sd){ seed= sd; count=0; }
float genP() { count++; return (rand_r(&seed))/float(RAND_MAX); } // [0,1]
int genI(int R) { count++; return (rand_r(&seed) % R); } // [0,R-1]
};
int main(int argc, char *argv[]){
long timePointOfProblem= 134065568;
nativeRandRUni* mainRGen= new nativeRandRUni(-158342163);
int rr;
//ofstream* fout_metaAux= new ofstream();
//fout_metaAux->open("random.numbers");
for(int i=0; i< timePointOfProblem; i++){
rr= mainRGen->genI(1009200);
//(*fout_metaAux) << rr << endl;
//if(i%1000==0) mainRGen->seed= 111111; //(*) FORCE
}
//fout_metaAux->close();
}
Given that random numbers is key to your simulation, you should implement your own generator. I don't know what algorithm rand_r is using, but it could be something pretty crappy like linear congruent generator.
I'd look into implementing something fast and with good qualities where you know the underlying algorithm. I'd start by looking at implementing Mersenne Twister:
http://en.wikipedia.org/wiki/Mersenne_twister
Its simple to implement and very fast - requires no divides.
ended up trying a simple solution from boost, changing the generator to:
class nativeRandRUni {
public:
typedef mt19937 EngineType;
typedef uniform_real<> DistributionType;
typedef variate_generator<EngineType, DistributionType> VariateGeneratorType;
nativeRandRUni(long s, float min, float max) : gen(EngineType(s), DistributionType(min, max)) {}
VariateGeneratorType gen;
};
I don't get the problem anymore... tho it solved it, i dont feel very comfortable with not understanding what it was. I think Rafael is right, i should not trust rand_r for this intensive number of generations
Now, this is slower than before, so i may look for ways of optimizing it.
QUESTION: Would a Mersenne Twister implementation in principle be faster?
and thanks to all!
I'm trying to generate a bunch of random numbers using rand() % (range).
Here's how my code is setup :
srand(time(NULL));
someClass *obj = new someClass(rand()%range1,rand()%range2... etc ); // i.e. a number of random numbers one after the other
Whenever I run this, it seems all the calls to rand() generate the same number. I tried doing it without the : (edit : all rand() do not generate the same number it seems , read edit at the end)
srand(time(NULL));
then , every execution of the program yields the same results.
Also, since all calls to rand() are in a constructor , I cant really reseed it all the time. I guess I can create all objects sent to the constructor beforehand and reseed the random number generator in between, but it seems like an inelegant solution.
How can I generate a bunch of different random numbers ?
edit: It seems because I was creating a lot of objects in a loop, so every time the loop iterated srand(time(NULL)) was reseeded and the sequence got reset ( as time(NULL) has a resolution of a second) , that's why all subsequent objects had very similar properties.
If you call srand once, then all subsequent rand calls will return (different) pseudorandom numbers. If they don't, you're doing it wrong. :)
Apart from this, rand is pretty useless. Boost.Random (or the C++11 standard library <random> header) provides much more powerful random number generators, with nicer, more modern interfaces as well (for example allowing you to have multiple independent generators, unlike rand which uses a single global seed)
Unless reseeded with a different starting point, rand() always returns the same sequence. That is actually a feature to make program tests repeatable!
So, you have to call srand if you want a different sequence for different runs. Perhaps you can do that before calling the first constructor?
Call srand once at the begin of the program. Then call rand()%range any time you want a random number. Here is an example for your situation, that works pretty well
#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
class Test
{
public:
Test(int num0,int num1, int num2):num0_(num0),num1_(num1),num2_(num2){}
int num0_,num1_,num2_;
};
int main()
{
srand(time(NULL));
Test *test=new Test(rand()%100,rand()%100,rand()%100);
cout << test->num0_ << "\n";
cout << test->num1_ << "\n";
cout << test->num2_ << "\n";
delete test;
return 0;
}
check this code at: http://ideone.com/xV0R3#view_edit_box
#include<iostream>
#include <stdio.h>
#include <stdlib.h>
#include<time.h>
using namespace std;
int main()
{
int i=0;
srand(time(NULL));
while(i<10)
{
cout<<rand()<<endl;
i++;
}
return 0;
}
this produces different random numbers. you need to call srand() only once. rand() generates a different number every time after the srand() call