How to get current seed from C++ rand()?

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 seed of rand() at any given time? This would give me the opportunity to store ONLY the current seeds and not full objects. (thus I could regenerate those objects, by regenerating the exact same sub-sequences of random numbers)

An exhaustive solution is storing the full sequence of random numbers given by rand() – doesn’t worth it. Another would be solution is to implement my own class for randomized numbers.

Google gave me no positive clues. There are hundreds of articles teaching the basics of rand and srand, and I couldn’t find the specific ones.

Does anyone know other random number generators with implemented seed-stealer?

Thank you for your fast answers! There are more possible answers/solutions to this question, so I made a list of your answers here.

SOLUTIONS:

  1. The short answer is: there is no standard way to get the seed

  2. The closest possible workaround is to save the INITIAL seed in the beginning, and count how many times you call the rand() function. I marked this as solution because it works on the current std::rand() function of every compiler (and this was the main question about). I’ve benchmarked my 2.0 GHz CPU, and found that I can call&count rand() 1,000,000,000 times in 35 seconds. This might sound good, but I have 80,000 calls to generate one object. This restricts the number of generations to 50,000 because the size of unsigned long. Anyway, here is my code:

    class rand2
    {
       unsigned long n;
    
       public:
    
       rand2 () : n(0) {}
    
       unsigned long rnd()
       {
          n++;
          return rand();
       }
       // get number of rand() calls inside this object
       unsigned long getno ()
       {
          return n;
       }
       // fast forward to a saved position called rec
       void fast_forward (unsigned long rec)
       {
          while (n < rec) rnd();
       }
    };
    
  3. Another way is to implement your own Pseudo-random number generator, like the one Matteo Italia suggested. This is the fastest, and possibly the BEST solution. You’re not restricted to 4,294,967,295 rand() calls, and don’t need to use other libraries either. It’s worth mentioning that different compilers have different generators. I’ve compared Matteo’s LCG with rand() in Mingw/GCC 3.4.2 and G++ 4.3.2. All 3 of them were different (with seed = 0).

  4. Use generators from C++11 or other libraries as Cubbi, Jerry Coffin and Mike Seymour suggested. This is the best idea, if you’re already working with them. Link for C++11 generators: http://en.cppreference.com/w/cpp/numeric/random (there are some algorithm descriptions here too)

C# – Get Seed from Sequence

Is it possible to get the seed from a Random() sequence in c#? My goal is to create a kind of editor, where the player creates his character, like he’d be able to choose in a set of different eyes, p

How to sample rows in MySQL using RAND(seed)?

I need to fetch a repeatable random set of rows from a table using MySQL. I implemented this using the MySQL RAND function using the bigint primary key of the row as the seed. Interestingly this produ

How do I seed the rand() function in Objective-C?

Part of what I’m developing is a random company name generator. It draws from several arrays of name parts. I use the rand() function to draw the random name parts. However, the same random numbers

What the equalivant code as SQL Server RAND ( [ seed ] )?

What the equivalent code in C# as SQL Server T-SQL RAND ( [ seed ] )?

python file object how to remove byte from current seed postion to end

python file object how to remove byte from current seed postion to end f = open(filename, a+) truncate_pos = f.tell() f.truncate(truncate_pos) seems not work,how could i do?

How to get the seed value from a random number generator in PHP

I would like to get the seed value after the rand() or mt_rand() is used. Essentially I want to store the seed so that I can use this seed to continue generating random numbers next time php is execut

How do you get the current seed of random in C#?

In my game I’m going to use random values to pick the reward the player gets from a chest. The problem is that you can quick save and quick load and that means they can keep reloading to re-randomize

How to get a larger random number from the c function rand()

I am in a coding environment where I only have access to some most basic c functions. #include’ing other lib is not feasible. In this environment, I can call rand() which gives me a random number betw

In C, how do I get a specific range of numbers from rand()?

srand(time(null)); printf(%d, rand()); Gives a high-range random number (0-32000ish), but I only need about 0-63 or 0-127, though I’m not sure how to go about it. Any help?

Can I get the current seed from a Mersenne Twister?

I’m adapting a Mersenne Twister in my Application, specifically mt19937ar.c from http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html – Code is mirrored on https://gist.github.com/ms

Answers

Use srand() to set the seed. save the value you used as the seed.

http://cplusplus.com/reference/clibrary/cstdlib/srand/

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;
    }
};

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.

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.

rand() does not offer any way to extract or duplicate the seed. The best you can do is store the initial value of the seed when you set it with srand(), and then reconstruct the whole sequence from that.

The Posix function rand_r() gives you control of the seed.

The C++11 library includes a random number library based on sequence-generating “engines”; these engines are copyable, and allow their state to be extracted and restored with << and >> operators, so that you can capture the state of a sequence at any time. Very similar libraries are available in TR1 and Boost, if you can’t use C++11 yet.

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.

I would recommend you to use the Mersenne Twister Pseudo-Random Number Generator. It is fast and offer very good random numbers. You can seed the generator in the constructor of the class very simply by

unsigned long rSeed = 10;
MTRand myRandGen(rSeed);

Then you just need to store somewhere the seeds you used to generate the sequences…

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:

  1. the same PRNG being used by the C library to expose both rand() and random() interfaces, and
  2. some knowledge about the default initialization of this PRNG in the C library (128 bytes state).

If 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).