I generate a few thousand object in my program based on the C++ rand() function. Keeping them in the memory would be exhaustive. Is there a way to copy the CURRENT
Use srand() to set the seed. save the value you used as the seed.
http://cplusplus.com/reference/clibrary/cstdlib/srand/
Does anyone know other random number generators with implemented seed-stealer
All standard C++11 random number generators (also available in TR1 and in Boost) offer this functionality. You can simply copy the generator objects or serialize/deserialize them.
Is there a way to copy the CURRENT seed of rand() at any given time?
What follows is an implementation-specific way to save and restore the pseudo-random number generator (PRNG) state that works with the C library on Ubuntu Linux (tested on 14.04 and 16.04).
#include <array>
#include <cstdlib>
#include <iostream>
using namespace std;
constexpr size_t StateSize = 128;
using RandState = array<char, StateSize>;
void save(RandState& state) {
RandState tmpState;
char* oldState = initstate(1, tmpState.data(), StateSize);
copy(oldState, oldState + StateSize, state.data());
setstate(oldState);
}
void restore(RandState& state) {
setstate(state.data());
}
int main() {
cout << "srand(1)\n";
srand(1);
cout << " rand(): " << rand() << '\n';
cout << " rand(): " << rand() << '\n';
cout << " rand(): " << rand() << '\n';
cout << " rand(): " << rand() << '\n';
cout << " rand(): " << rand() << '\n';
cout << " rand(): " << rand() << '\n';
cout << " rand(): " << rand() << '\n';
cout << " rand(): " << rand() << '\n';
cout << "srand(1)\n";
srand(1);
cout << " rand(): " << rand() << '\n';
cout << " rand(): " << rand() << '\n';
cout << " rand(): " << rand() << '\n';
cout << " rand(): " << rand() << '\n';
cout << "save()\n";
RandState state;
save(state);
cout << " rand(): " << rand() << '\n';
cout << " rand(): " << rand() << '\n';
cout << " rand(): " << rand() << '\n';
cout << " rand(): " << rand() << '\n';
cout << "restore()\n";
restore(state);
cout << " rand(): " << rand() << '\n';
cout << " rand(): " << rand() << '\n';
cout << " rand(): " << rand() << '\n';
cout << " rand(): " << rand() << '\n';
}
This relies on:
rand()
and random()
interfaces, andIf run, this should output:
srand(1)
rand(): 1804289383
rand(): 846930886
rand(): 1681692777
rand(): 1714636915
rand(): 1957747793
rand(): 424238335
rand(): 719885386
rand(): 1649760492
srand(1)
rand(): 1804289383
rand(): 846930886
rand(): 1681692777
rand(): 1714636915
save()
rand(): 1957747793
rand(): 424238335
rand(): 719885386
rand(): 1649760492
restore()
rand(): 1957747793
rand(): 424238335
rand(): 719885386
rand(): 1649760492
This solution can help in some cases (code that can't be changed, reproducing execution for debugging purpose, etc...), but it is obviously not recommended as a general one (e.g. use C++11 PRNG which properly support this).
There's no standard way to obtain the current seed (you can only set it via srand
), but you can reimplement rand()
(which is usually a linear congruential generator) by yourself in a few lines of code:
class LCG
{
private:
unsigned long next = 1;
public:
LCG(unsigned long seed) : next(seed) {}
const unsigned long rand_max = 32767
int rand()
{
next = next * 1103515245 + 12345;
return (unsigned int)(next/65536) % 32768;
}
void reseed(unsigned long seed)
{
next = seed;
}
unsigned long getseed()
{
return next;
}
};
You could try saving the value that you used to seed right before (or after) the srand.
So, for example:
int seed = time(NULL);
srand(time(NULL));
cout << seed << endl;
cout << time(NULL);
The two values should be the same.
The random number generation classes in C++11 support operator<<
to store their state (mostly the seed) and operator>>
to read it back in. So, basically, before you create your objects, save the state, then when you need to re-generate same sequence, read the state back in, and off you go.