Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java's Random values differ each time

Tags:

java

random

I want the Random to return the same values each time. So I tried giving it a const seed. But it still returns random values. How can I stop this?

EDIT: I use the same Random object all over my code, The first time I tested my program I got the following values from the random:

13, 9, 10, 12, 14, 11, 15, 10, 8, 6, 12, 9, 7, 7, 6, 1, 0, 0, 0, 80, 33, 3, 0, 45, 6, 2, 51, 50, 3, 0, 1, 1, 0, 2, 3, 0, 0, 2, 0, 3, 0, 1, 33, 1, 22, 7, 55, 92, 33, 1, 5, 6, 10, 2, 1, 85, 26, 1, 3, 42, 16, 0, 2, 34, 0, 1, 2, 8, 0, 73, 1, 4, 66, 59, 49, 99, 2, 4, 97, 57, 85, 28, 0, 2, 3, 9, 36, 1, 19, 4, 0, 71, 9, 2, 3, 76, 6, 3, 0, 96, 84, 22, 0, 0, 1, 1, 0, 1, 0, 0, 2, 0, 0, 0, 0, 58, 2, 1, 2, 1, 0, 1, 5, 0, 0, 1, 0, 4, 21, 59, 3, 1, 6, 3, 6, 0, 0, 3, 2, 2, 3, 5, 3, 0, 6, 5, 60, 3, 4, 4, 2, 6, 1, 3, 5, 1, 5, 26, 4, 0, 25, 5, 0, 61, 2, 0, 29, 2, 1, 34, 57, 55, 61, 1, 1, 21, 6, 1, 3, 0, 56, 6, 23, 6, 0, 47, 1, 1, 55, 0, 0, 5, 1, 4, 0, 57, 21, 45, 2, 0, 3, 0, 6, 1, 64, 39, 2, 0, 51, 31, 13, 9, 10, 12, 14, 11, 15, 10, 8, 6, 12, 9, 7, 7, 6, 1, 0, 0, 0, 80, 33, 3, 0, 45, 6, 2, 51, 50, 3, 0, 1, 1, 0, 2, 3, 0, 0, 2, 0, 3, 0, 1, 33, 1, 22, 7, 55, 92, 33, 1, 5, 6, 10, 2, 1, 85, 26, 1, 3, 42, 16, 0, 2, 34, 0, 1, 2, 8, 0, 73, 1, 4, 66, 59, 49, 99, 2, 4, 97, 57, 85, 28, 0, 2, 3, 9, 36, 1, 19, 4, 0, 71, 9, 2, 3, 76, 6, 3, 0, 96, 84, 22, 0, 0, 1, 1, 0, 1, 0, 0, 2, 0, 0, 0, 0, 58, 2, 1, 2, 1, 0, 1, 5, 0, 0, 1, 0, 4, 21, 59, 3, 1, 6, 3, 6, 0, 0, 3, 2, 2, 3, 5, 3, 0, 6, 5, 60, 3, 4, 4, 2, 6, 1, 3, 5, 1, 5, 26, 4, 0, 25, 5, 0, 61, 2, 0, 29, 2, 1, 34, 57, 55, 61, 1, 1, 21, 6, 1, 3, 0, 56, 6, 23, 6, 0, 47, 1, 1, 55, 0, 0, 5, 1, 4, 0, 57, 21, 45, 2, 0, 3, 0, 6, 1, 64, 39, 2, 0, 51, 31

The second time I got:

13, 9, 10, 12, 14, 11, 15, 10, 8, 6, 12, 9, 7, 7, 6, 1, 0, 0, 0, 2, 1, 1, 3, 1, 0, 33, 9, 61, 1, 2, 54, 59, 99, 28, 0, 88, 11, 0, 0, 92, 24, 0, 47, 43, 83, 13, 1, 1, 53, 46, 22, 0, 2, 0, 0, 0, 0, 2, 0, 13, 8, 1, 16, 6, 2, 34, 0, 1, 2, 8, 0, 73, 1, 4, 66, 59, 49, 99, 2, 0, 97, 57, 85, 28, 5, 2, 3, 3, 36, 4, 19, 0, 0, 71, 9, 2, 3, 76, 6, 0, 0, 0, 2, 4, 2, 0, 1, 0, 1, 1, 0, 0, 0, 2, 6, 1, 58, 2, 1, 2, 1, 0, 1, 5, 0, 0, 0, 0, 4, 21, 59, 3, 1, 6, 3, 6, 0, 0, 3, 2, 2, 3, 5, 3, 0, 6, 5, 60, 3, 4, 4, 2, 6, 1, 3, 5, 1, 5, 26, 4, 0, 25, 5, 0, 61, 2, 0, 29, 2, 1, 34, 57, 55, 61, 1, 1, 21, 6, 1, 3, 0, 56, 6, 23, 6, 0, 47, 1, 1, 55, 0, 0, 5, 1, 4, 0, 57, 21, 45, 2, 0, 13, 9, 10, 12, 14, 11, 15, 10, 8, 6, 12, 9, 7, 7, 6, 1, 0, 0, 0, 2, 1, 1, 3, 1, 0, 33, 9, 61, 1, 2, 54, 59, 99, 28, 0, 88, 11, 0, 0, 92, 24, 0, 47, 43, 83, 13, 1, 1, 53, 46, 22, 0, 2, 0, 0, 0, 0, 2, 0, 13, 8, 1, 16, 6, 2, 34, 0, 1, 2, 8, 0, 73, 1, 4, 66, 59, 49, 99, 2, 0, 97, 57, 85, 28, 5, 2, 3, 3, 36, 4, 19, 0, 0, 71, 9, 2, 3, 76, 6, 0, 0, 0, 2, 4, 2, 0, 1, 0, 1, 1, 0, 0, 0, 2, 6, 1, 58, 2, 1, 2, 1, 0, 1, 5, 0, 0, 0, 0, 4, 21, 59, 3, 1, 6, 3, 6, 0, 0, 3, 2, 2, 3, 5, 3, 0, 6, 5, 60, 3, 4, 4, 2, 6, 1, 3, 5, 1, 5, 26, 4, 0, 25, 5, 0, 61, 2, 0, 29, 2, 1, 34, 57, 55, 61, 1, 1, 21, 6, 1, 3, 0, 56, 6, 23, 6, 0, 47, 1, 1, 55, 0, 0, 5, 1, 4, 0, 57, 21, 45, 2, 0

The first couple of values are quite similar but the rest. Well, you can see

I use private static Random r = new Random(SEED); // The seed is never changed after this point I also use this random to randomize byte arrays. The thing is, I'm getting different outputs for the same input. I wish I could post more code but it's a really big project to post here.

like image 964
Eyad Salah Avatar asked Dec 23 '22 03:12

Eyad Salah


2 Answers

I can only see two ways in which this can happen:

  1. The two executions don't share precisely the same order of invocation. There's something you're missing - e.g. some method invocation on the random object from some other thread or something. As PRNGs are completely deterministic, this is the most likely thing - I'm sure you already checked it but it still seems the most likely explanation.

  2. You've found a bug in the PRNG. Unlikely but not impossible - if you provide us with details like Java version, seed used, etc. then maybe we could try and reproduce it.

In any case, I would strongly recommend you create an "as short as possible" toy-application which can replicate the discrepancy, and then update your question with it if the problem persists.

like image 110
Oak Avatar answered Jan 12 '23 00:01

Oak


The following snippet of code should always produce the same output:

import java.util.Random;
public class Test {
    public static void main(String... args) {
        Random r = new Random(123456L);     // use the seed 123456L
        System.out.println(r.nextInt(10));
        System.out.println(r.nextInt(10));
        System.out.println(r.nextInt(10));
        System.out.println(r.nextInt(10));
    }
}

Output:

3
7
7
5

To go back to "real" random behavior, simply remove the argument to the constructor (and it will pick a "random" seed).


For more information, see the API-docs for Random:

Random

public Random(long seed)

Creates a new random number generator using a single long seed. The seed is the initial value of the internal state of the pseudorandom number generator which is maintained by method next(int).

The invocation new Random(seed) is equivalent to:

Random rnd = new Random();
rnd.setSeed(seed);

Parameters:
seed - the initial seed
See Also:
setSeed(long)


If you want r.nextInt(10) to return the same number every call, you need to do:

        r.setSeed(123456L);
        System.out.println(r.nextInt(10));
        r.setSeed(123456L);
        System.out.println(r.nextInt(10));
        r.setSeed(123456L);
        System.out.println(r.nextInt(10));
        r.setSeed(123456L);
        System.out.println(r.nextInt(10));
like image 22
aioobe Avatar answered Jan 12 '23 00:01

aioobe