Generation of the same sequence of random numbers

后端 未结 5 1857
广开言路
广开言路 2021-01-07 20:42

I want to generate random numbers in java, I know I should use existing methods like Math.random(), however, my question is: how can I generate the same sequence of numbers,

相关标签:
5条回答
  • 2021-01-07 21:17

    An example of using the same seed repeatedly.

    public static void main(String... args) throws IOException {
        printDoublesForSeed(1);
        printDoublesForSeed(128);
        printDoublesForSeed(1);
        printDoublesForSeed(128);
    }
    
    private static void printDoublesForSeed(long seed) {
        double[] doubles = new double[10];
        Random rand = new Random(seed);
        for (int j = 0; j < doubles.length; j++) {
            doubles[j] = (long) (rand.nextDouble() * 100) / 100.0;
        }
        System.out.println("doubles with seed " + seed + " " + Arrays.toString(doubles));
    }
    

    prints

    doubles with seed 1 [0.73, 0.41, 0.2, 0.33, 0.96, 0.0, 0.96, 0.93, 0.94, 0.93]
    doubles with seed 128 [0.74, 0.53, 0.63, 0.41, 0.21, 0.2, 0.33, 0.74, 0.17, 0.47]
    doubles with seed 1 [0.73, 0.41, 0.2, 0.33, 0.96, 0.0, 0.96, 0.93, 0.94, 0.93]
    doubles with seed 128 [0.74, 0.53, 0.63, 0.41, 0.21, 0.2, 0.33, 0.74, 0.17, 0.47]
    

    EDIT An interesting abuse of random seeds.

    public static void main(String ... args) {
        System.out.println(randomString(-6225973)+' '+randomString(1598025));
    }
    
    public static String randomString(int seed) {
        Random rand = new Random(seed);
        StringBuilder sb = new StringBuilder();
        for(int i=0;i<5;i++)
            sb.append((char) ('a' + rand.nextInt(26)));
        return sb.toString();
    }
    

    prints

    hello world
    
    0 讨论(0)
  • 2021-01-07 21:19

    Math.random is just a wrapper of the class java.util.Random. The first time you call Math.random an instance of the class java.util.Random is created.

    Now, most API's don't expose any true random number generators, because they cannot be implemented in software. Instead, they use pseudo-random number generators, which generate a sequence of random-looking numbers using a bunch of formulas. This is what java.util.Random does. However, every pseudo-random number generator needs to be seeded first. If you have two pseudo-random number generators which use the same algorithm and use the same seed, they will produce the same output.

    By default, java.util.Random uses the milliseconds since January 1, 1970 as the seed. Therefore, everytime you start your program, it will produce different numbers (unless you manage it to start java up in under 1 millisecond). So, the solution to your problem is to create your own java.util.Random instance and seed it by yourself:

    import java.util.Random;
    
    class ... {
        Random randomNumberGenerator = new Random(199711);
    
        public void ...()
        {
            int randomInt = randomNumberGenerator.nextInt();
            double randomDouble = randomNumberGenerator.nextDouble();
        }
    }
    

    The randomNumberGenerator will always spit out the same sequence of numbers, as long as you don't change the seed(the 199711).

    0 讨论(0)
  • 2021-01-07 21:22

    Sure - just create an instance of Random instead of using Math.random(), and always specify the same seed:

    Random random = new Random(10000); // Or whatever seed - maybe configurable
    int diceRoll = random.nextInt(6) + 1; // etc
    

    Note that it becomes harder if your application has multiple threads involved, as the timing becomes less predictable.

    This takes advantage of Random being a pseudo-random number generator - in other words, each time you ask it for a new result, it manipulates internal state to give you a random-looking sequence, but knowing the seed (or indeed the current internal state) it's entirely predictable.

    0 讨论(0)
  • 2021-01-07 21:24

    You need to seed the random number generator.

    Random random = new Random(aFixedNumber);
    random.nextInt();  // will always be the same
    
    0 讨论(0)
  • 2021-01-07 21:32

    I'd hardcode the numbers into the app. This takes more memory but is much faster.

    Just print random numbers to the terminal, then copy-paste them to your code.

    Be sure to leave a comment explaining what you have done, or they will look like black magic to the uninformed reader.

    0 讨论(0)
提交回复
热议问题