Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get nth number in sequence of rand() directly without having to call rand() n times?

According to my understanding, setting srand with a particular seed causes the sequence of calls to rand() to produce the same series of numbers each time for that particular seed:

Eg:

             srand(seed1);
             rand() // firstnumber (e.g.: 42)
             rand() // second number (e.g: 17)
             srand(seed1)
             rand() // first number (same as above (42))
             rand() // second number (same as above (17))

Is there a way to get the nth number in the sequence directly without having to call rand() n times ?

  • For example, if I want the 17th random number in the series, I want to get the number in one call, instead of calling rand() 17 times.

  • I cannot precompute and store the values

EDIT: I was looking at this article :

https://mathoverflow.net/questions/104915/pseudo-random-algorithm-allowing-o1-computation-of-nth-element

The answer on linear feedback shift registers seems to do it, but rather than implement it myself, I would rather use a trusted implementation, since this seems like a common problem.

EDIT: The reason I want to "jump" to the nth term, is because I use rand in different classes with different seeds, and I keep jumping back and forth between each class. I want the sequence in each class to continue where it left off, instead of starting from the first number each time. This is a single threaded application.

EDIT: When writing the post, I used the term PRNG. But really I'm just looking for a function which appears to produce random number. I'm using this for graphics, so there is no security problem. I use the random numbers to produce slight offsets in pixels.

  • I just need a function which is fast.
  • Appears to produce random numbers, but doesn't have to be of the kind used in security applications.
  • Have to be able to calculate the nth number in O(1) time.

Edit: Made a mistake - storing state isn't enough. I need to calculate nth random number in series in O(1) time. Since within the same class there may be multiple calls for the same nth term, storing state won't be enough, and I need to compute the nth term in O(1)

like image 209
Rahul Iyer Avatar asked Feb 22 '14 02:02

Rahul Iyer


People also ask

Why is rand () giving me the same number?

Accepted Answer This is because MATLAB's random number generator is initialized to the same state each time MATLAB starts up. If you wish to generate different random values in each MATLAB session, you can use the system clock to initialize the random number generator once at the beginning of each MATLAB session.

What is difference between rand () and Srand ()?

The rand() function in C++ is used to generate random numbers; it will generate the same number every time we run the program. In order to seed the rand() function, srand(unsigned int seed) is used. The srand() function sets the initial point for generating the pseudo-random numbers.

Does rand () include 1?

@jonas: the rand documentation states "returns a single uniformly distributed random number in the interval (0,1)", so it clearly excludes zero and one.


2 Answers

All of the C++11 PRNGs have a "discard" function, e.g.

#include <random>
#include <iostream>

int main() {
    std::mt19937 rng;
    static const size_t distance = 5;

    rng.seed(0);
    rng.discard(distance);
    std::cout << "after discard 5: " << rng() << '\n';

    rng.seed(0);
    for (size_t i = 0; i <= distance; ++i) {
        std::cout << i << ": " << rng() << '\n';
    }
}

http://ideone.com/0zeRNq

after discard 5: 3684848379
0: 2357136044
1: 2546248239
2: 3071714933
3: 3626093760
4: 2588848963
5: 3684848379
like image 63
kfsone Avatar answered Sep 30 '22 02:09

kfsone


Make your own rand and store one in each class. Of course this is the weakest PRNG. The point is you can have multiple PRNG active at once.

class Rand {
    int seed;
    const int a = 1103515245;
    const int c = 12345;
public:
    Rand();
    void srand( int );
    int rand();
};

Rand::Rand() : seed(123456789) {}

void Rand::srand( int s ) { seed = s; }

int Rand::rand()
{
  seed = a * seed + c;
  return seed;
}

The OP asks for "I use rand in different classes with different seeds". Each instance of Rand has its own seed. So place an instance of Rand in each object that needs its own seed.

like image 43
brian beuning Avatar answered Sep 30 '22 00:09

brian beuning