'Resumable' random number generation

I need deterministic random number generation that I can save and restore at a later point. Annoyingly, java.util.Random doesn’t allow you to get the current seed, only to set one. java.security.SecureRandom seems to let you get the current seed, so that’s one alternative but I’m worried about the speed implications.

Anyone have any other alternatives? (Or, anyone used SecureRandom for this and found that it’s fine?)

Thanks.

Use reflection to read the private field holding the seed.

From a design perspective, why would they make that field private and not provide a getter? :persecutioncomplex: Are we not supposed to know seeds?

I issue is that in Random, the ‘seed’ is supposed to be a conceptual seed, not a state.

In theory, the seed of a Random should be final, it will never change - like the seed of a tree never changes, it’s just that the seed transforms into something completely different.

Whether that was the reasoning of the Sun developers… I don’t know :slight_smile:

I understand why it’s final, but it seems natural to me to have the option to check what seed a particular generator is working with. I’d assume it’s for security though, but that doesn’t make sence if you can grab it by reflection anyway.

@Orangy: Why don’t you provide the seed yourself, and save it before entering it into the Random object?

Here is the source for Random:

http://developer.classpath.org/doc/java/util/Random-source.html

How about just making your own implementation without hasseling around with strange workarounds.

Just modify it and grab the seed anyway you want

Why not just set the seed when you need to “save” it?

If you need a midpoint snapshot you can always get a random from the current generator then set that as the seed…

It’s a pretty common use case in pure functional code to “fork” a PRNG. Now and again, even Java code takes a jaunt into functional land. Random is serializable, and the serialized form does include the seed. This means you can deep-copy the RNG by serializing it, then use that copy to restore the state from whatever snapshot you took. Would have been nice if it were also Cloneable but you can’t have everything.

The same goes for ThreadLocalRandom, which you really ought to be using. You can’t use SecureRandom for this, because it truly is nondeterministic.

Also, recall that as long as you’re not in an applet sandbox, you can always blow through access modifiers like private with reflection. Mind the inherent thread-unsafety of this though (making ThreadLocalRandom that much more ideal)

Don’t use reflection… :cranky:
Ideally, just adapt existing code or write your own class. You can also override Random and change the next(int) method.
SecureRandom can behave deterministically or not depending on the implementation you choose.
You really should be able to get a copy of a Random object, and Random should have been abstract or an interface.

public class SomeRandomClass extends Random
{
  private long state;

  public SomeRandomClass(long seed)
  {
    state = seed;
  }

  protected int next(int bits)
  {
    state = (state * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1);
    return (int)(state >>> (48 - bits));
  }

  public long getSomeRandomClassState()
  {
    return state;
  }

  public void setState(long state) // Not the same as set seed
  {
    this.state = state;
  }
}

sproingie already touched on this, but basically I want to fork/save/reset a Random object. Something like:


Random random = new Random(1234);

// use some random numbers
random.nextInt()
..

// Save the random state
long savedSeed = random.getSeed();

// use some more random numbers
int a = random.nextInt();
int b = random.nextInt();

// Rewind the random sequence
random = new Random(savedSeed);

// get the same sequence again
int c = random.nextInt(); // 'a' == 'c'
int d = random.nextInt(); // 'b' == 'd'

It’s late now so I’ll read this thread properly later, but I’m not keen on serialization or reflection tricks. I’ll have a look into forking java.util.Random if I can’t find any other open-source rngs.

Just implement something like Xorshift or WELL512 and add get/set functions for the internal state.

I really like Xorshift. It’s very fast and it passes most PRNG test suites (like diehard), too. Its internal state are just 4 ints.

Well, xorshift state can be any number of 32 or 64 bit integers. For 100-ulp(100) % of video game purposes any (well chosen set of constants) single integer state versions of either is already overkill. But that’s OK because they’re fast. Don’t bother with anything “better” because it’ll be over-engineering. (As an aside I find that the WELL1024 is faster than WELL512)