2

For example:

If rprng(seed,index) is my function, then for any pair of (seed,index), I should always get the same value for a given (seed,index).

For example:

rprng(4,2) = 17
rprng(4,5) = 21
rprng(4,2) = 17 
Purushotham
  • 3,770
  • 29
  • 41
Rahul Iyer
  • 19,924
  • 21
  • 96
  • 190
  • But it has to be pseudorandom! – Rahul Iyer Feb 20 '14 at 13:54
  • 2
    Pseudorandom != random. Pseudorandom is still just mathematics. – Simple Feb 20 '14 at 13:58
  • I know that, but the numbers still have to appear random. I don't know how to make up a bunch of numbers – Rahul Iyer Feb 20 '14 at 14:02
  • I'm not confused at all. I just want a function that generates numbers in a sequence that appears to be random but isn't random, and can be repeated given a seed and index. – Rahul Iyer Feb 20 '14 at 14:03
  • @John That's what `rand` does (if you call it `index` times with the same seed). – molbdnilo Feb 20 '14 at 14:07
  • 1
    Okay, scratch that. You just seem like you didn't do any research. Have a look at decent existing PRNGs, such as a multiply-with-carry, linear congruential generator, or if you can stomach it, the Mersenne twister. What's your problem? You're not expected to create a good, original PRNG yourself, in fact you probably shouldn't try. Also, your notation *is* unusual. PRNGs are typically considered as streams rather than random-access, i.e. `prng(state)` returns the next number and alters the state, a function like `prng(seed, i)` (usually called `skip`) either doesn't exist or is secondary. –  Feb 20 '14 at 14:07
  • you could implement something on your own like http://en.m.wikipedia.org/wiki/Rule_30 if you needed to be portable. – Grady Player Feb 20 '14 at 15:23
  • So far you've stated requirements. **What have you tried so far?** What research have you done? – Eric Lippert Feb 20 '14 at 15:52
  • 1
    Use a hash function. I'd use SipHash (possibly with fewer rounds), with the seed as key and the index as message. – CodesInChaos Feb 21 '14 at 11:56
  • 2
    @delnan, it's very true that PRNGs are usually discussed as streams, and the kind of feature John is asking for is absent or secondary. That's why John may have done research and not found what he needs. There are important areas (like procedural textures) where "random access" (to use a term confusingly) to PR numbers is important: or to put it another way, where PRNGs need to be stateless, so that we can recompute random(a1, a2, ... an) on many different threads, over many display frames, and always get consistent results. – LarsH Jan 05 '17 at 15:26
  • For a straightforward answer for the similar Python question see https://stackoverflow.com/a/9024521/395029 – Brent Aug 04 '20 at 19:28

3 Answers3

2

A simple idea is to use a PRNG that is so thorough that the values generated by seed, seed+1, seed+2... are acceptably random. E.g.:

#include <random>

unsigned prng(unsigned seed, unsigned index)
{
  thread_local std::mt19937 engine;  // or a different engine
  engine.seed(seed + index);

  return engine();
}

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

Community
  • 1
  • 1
manlio
  • 18,345
  • 14
  • 76
  • 126
  • 1
    Actually, taking the 0th random number from a sequentially seeded PRNG is often not acceptably random. See https://blogs.unity3d.com/2015/01/07/a-primer-on-repeatable-random-numbers/ under "Can’t I just use random number generators with different seed values?" where exactly this "common misconception" is addressed and the poor results are demonstrated. How do you find a PRNG that is "so thorough", when most PRNGs are not designed to be used in this way? However the question you linked to on mathoverflow.net does have good answers: use a (good) hash or LFSR. – LarsH Jan 05 '17 at 15:34
  • @LarsH Very interesting remark. Perhaps the fact that the single value constructor of the Mersenne Twister performs a simple (sort of) warm up (e.g. http://stackoverflow.com/a/15509942/3235496 and comments) could mitigate such a problem (?) – manlio Jan 16 '17 at 14:09
  • Maybe. It would be worth testing. One test is to plot the first 65536 values generated this way as gray values on a 256x256 grid. Another is to draw a white dot at the first 65536 coordinate pairs generated in this way. (Also from https://blogs.unity3d.com/2015/01/07/a-primer-on-repeatable-random-numbers/) – LarsH Jan 16 '17 at 14:44
1

Use srand(seed) and all uses of myval=rand() that follow will be pseudo random. I often use this method as it is the easiest way of getting the same values from any given seed.

WLGfx
  • 1,169
  • 15
  • 31
0
int rprng(int seed, int index){
    srand(seed);
    while(index-- >0)
        rand();
    return rand();
}
BLUEPIXY
  • 39,699
  • 7
  • 33
  • 70
  • 1
    While this is correct, the time complexity is O(index), i.e. linear. Why use an inefficient algorithm when there are good constant-time algorithms to choose from? See http://mathoverflow.net/questions/104915/pseudo-random-algorithm-allowing-o1-computation-of-nth-element – LarsH Jan 05 '17 at 15:30