Java Random Always Returns the Same Number When I Set the Seed

Java random always returns the same number when I set the seed?

You need to share the Random() instance across the whole class:

public class Numbers {
Random randnum;

public Numbers() {
randnum = new Random();
randnum.setSeed(123456789);
}

public int random(int i){
return randnum.nextInt(i);
}
}

Random() always picks the same number using a seed

In the loop, you don't want to reset the Random Number Generator, I assume?

In the example, you could do:

 Clas c1 = new Clas();
for(int i=0; i<100; i++)
{
Helper h = new Helper(c1);
System.out.println(h.getR());
}

In your original example, you seem to have multiple Tree instances, so you can't use this. But you can declare your Random static, so it is shared among all Trees:

static Random rand = new Random(1825897);

Random generator giving me the same number everytime

You're providing a constant seed value to the random number generator:

Random gen = new Random(1535636);  

Don't do that. It will always provide the same values. Just call the default constructor:

Random gen = new Random();

That

Creates a new random number generator. Its seed is initialized to a value based on the current time:

http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Random.html#Random()


Why?

As with most "standard library" random number generators, Random is a "Pseudorandom number generator". That means it is not actually generating random numbers! Instead, it is calculating them in a very defined fashion - they just look like random numbers, and they tend to have a decent distribution.

PRNGs are initialized with a seed value which sets their internal state. If you provide the same seed value every time, the PRNG is going to be in the same state every time you run it, and thus, provide the same sequence of numbers!

The thing that makes them seem random all the time, is that usually1 they are "seeded" by default with a time-based value. In most libraries this is a time-dervied value with very good precision. So most of the time, if you see someone seeding their PRNG, it is probably incorrect, or at least very unnecessary.

1 - Note: This is not the case with rand() from libc: "If no seed value is provided, the rand() function is automatically seeded with a value of 1."

Java Random.nextInt(int) return the same value when set different seeds

As far as I know, different seeds produce different values

This is incorrect, different seeds may produce different values, they can also produce the same values.

There are 2^64 possible seeds and rand.nextInt(256) can only return 256 different values so many of the seeds must return the same value.

Also the setSeed javadoc states

The implementation of setSeed by class Random happens to use only 48
bits of the given seed

So if your seed differs in only the ignored bits all of the values will be the same.

Random numbers always in same order

This is what you really need to refer to https://stackoverflow.com/a/11705615/1143977. Quoting my answer from the reference link.

There are two issues causing what you see. The first is that the code sets a seed value for a Random instance. The second is that the instance method "random" instances a new Random object and then immediately sets its seed with the same seed every time. The combination of these two guarantees that, for the same value of i, the method "random" will always return the same value and it will always be the first in the sequence that the seed always generates.

Assuming setting the seed is mandatory, to get the next value in the sequence instead of the same first value of the sequence every time, the randnum instance of Random can't have its seed set every time just before its next method gets called. To fix that, move the randnum local variable instance of Random from the scope of the random instance method to the class scope. Second, set the seed only when random is assigned a Random instance or only to get same sequence of results from it to start over again. Class Random's setSeed(long seed) instance method can't execute in the class scope, so the constructor has to set it using the Random constructor with the long seed parameter. The following code shows the changes:

public class RandomDemo { // arbitrary example class name
// lots of class related stuff may be here...

// still inside the class scope...
// private is a good idea unless an external method needs to change it
private Random randnum = new Random(123456789L);
// the seed guarantees it will always produce the same sequence
// of pseudo-random values when the next methods get called
// for unpredicable sequences, use the following constructor instead:
// private Random randnum = new Random();

// lots of code may be here...

// publicly exposed instance method for getting random number
// from a sequence determined by seed 123456789L
// in the range from 0 through i-1
public int randnum(int i) {
// don't set the seed in here, or randnum will return the exact same integer
// for the same value of i on every method call
// nextInt(i) will give the next value from randnum conforming to range i
return randnum.nextInt(i);
} // end randnum

// lots of more code may be here...

} // end class RandDemo

The above will give you an exact solution to your exact problem, as stated. However, using a mandatory seed seems unusual, given what it does.

The following explains more about Random, seeds for Random and why there is a provision for supplying a seed.

Random has two constructors:

Random()

and

Random(long seed)

and an instance method

setSeed(long seed)

that all affect the sequence of numbers obtained from a Random instance. The instance method,

setSeed(long seed)

sets the Random object to the same state it would have been in had it been just instanced with the same seed as the constructor argument. Only the low-order 48 bits of a seed value get used.

If a Random object is instanced without a seed, the seed will be the same as the system time in milliseconds. This ensures that, unless two Random objects are instanced in the same millisecond, they will produce different pseudo-random sequences. Only the low order 48 bits of the seed value gets used. This causes unpredictable pseudo-random sequences. It is not necessary and wasteful of computing resources to get a new instance of Random every time one calls a next method.

Random's seed parameters are provided so that one may instance a Random object that produces a sequence that is repeatable. For a given seed, the sequence of values in next methods are guaranteed to be the same sequence whenever that seed is used. This is useful for testing software that is going to use pseudo-random sequences where results have to be predicable and repeatable. It is not useful for creating different unpredictable pseudo-random sequences in operation.

Generating the same random number?

The Random class is a pseudo-random series generator, meaning that if you initialize it with the same seed that it will return the exact same series. So initialize Random with a combination of your arguments and request a new float number.

public static float random(int seed, int x, int y) {
long superSeed = (seed << 32) ^ (x << 16) ^ y; // combine into a single long
return new Random(superSeed).nextFloat();
}

Update

If I can interpret your question as: "How can I always generate the same terrain from a seed (with a single new Random() call?", then I would use something like this:

public static float[][] randomTerrain(long seed, int w, int h) {
Random random = new Random(seed);
float[][] terrainRandom = new float[w][h];
for (int x = 0; x < w; x += 1) {
for (int y = 0; y < h; y += 1) {
terrainRandom[x][y] = random.nextFloat();
}
}
return terrainRandom;
}

This will generate the same array of randomness from the same seed every time.

This stores the randomness in an array, but you could actually integrate this into your terrain generating code so you don't really have to store the entire array first before using it.

First random number after setSeed in Java always similar

The Random class is designed to be a low overhead source of pseudo-random numbers. But the consequence of the "low overhead" implementation is that the number stream has properties that are a long way off perfect ... from a statistical perspective. You have encountered one of the imperfections. Random is documented as being a Linear Congruential generator, and the properties of such generators are well known.

There are a variety of ways of dealing with this. For example, if you are careful you can hide some of the most obvious "poor" characteristics. (But you would be advised to run some statistical tests. You can't see non-randomness in the noise added to your second image, but it could still be there.)

Alternatively, if you want pseudo-random numbers that have guaranteed good statistical properties, then you should be using SecureRandom instead of Random. It has significantly higher overheads, but you can be assured that many "smart people" will have spent a lot of time on the design, testing and analysis of the algorithms.

Finally, it is relatively simple to create a subclass of Random that uses an alternative algorithm for generating the numbers; see link. The problem is that you have to select (or design) and implement an appropriate algorithm.


Calling this an "issue" is debatable. It is a well known and understood property of LCGs, and use of LCGs was a concious engineering choice. People want low overhead PRNGs, but low overhead PRNGs have poor properties. TANSTAAFL.

Certainly, this is not something that Oracle would contemplate changing in Random. Indeed, the reasons for not changing are stated clearly in the javadoc for the Random class.

"In order to guarantee this property, particular algorithms are specified for the class Random. Java implementations must use all the algorithms shown here for the class Random, for the sake of absolute portability of Java code."

Java random numbers using a seed

If you're giving the same seed, that's normal. That's an important feature allowing tests.

Check this to understand pseudo random generation and seeds:

Pseudorandom number generator

A pseudorandom number generator (PRNG), also known as a deterministic
random bit generator DRBG, is an algorithm for generating a sequence
of numbers that approximates the properties of random numbers. The
sequence is not truly random in that it is completely determined by
a relatively small set of initial values, called the PRNG's state,
which includes a truly random seed.

If you want to have different sequences (the usual case when not tuning or debugging the algorithm), you should call the zero argument constructor which uses the nanoTime to try to get a different seed every time. This Random instance should of course be kept outside of your method.

Your code should probably be like this:

private Random generator = new Random();
double randomGenerator() {
return generator.nextDouble()*0.5;
}


Related Topics



Leave a reply



Submit