Случайные числа Java с использованием семени

Это мой код для генерации случайных чисел, используя семя в качестве аргумента:

double randomGenerator(long seed) {
    Random generator = new Random(seed);
    double num = generator.nextDouble() * (0.5);

    return num;
}

каждый раз, когда я даю семя и пытаюсь сгенерировать 100 чисел, все они одинаковы.
Как я могу это исправить?

7 ответов


Если вы даете одно и то же семя, это нормально. Это важная функция, позволяющая проводить тесты.

проверьте это, чтобы понять псевдослучайную генерацию и семена:

генератор псевдослучайных чисел

генератор псевдослучайных чисел (PRNG), также известный как детерминированный генератор случайных битов DRBG, представляет собой алгоритм генерации последовательности чисел, аппроксимирующих свойства случайных чисел. Этот последовательность не является действительно случайной в том, что она полностью определяется относительно небольшой набор начальных значений, называемый состоянием PRNG, что включает в себя действительно случайное семя.

Если вы хотите иметь разные последовательности (обычный случай, когда вы не настраиваете или не отлаживаете алгоритм), вы должны вызвать конструктор нулевого аргумента, который использует nanoTime, чтобы попытаться получить другое семя каждый раз. Это Random экземпляр, конечно, должен храниться вне ваш метод.

ваш код, вероятно, должен быть такой:

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

простой способ использовать:

Random rand = new Random(System.currentTimeMillis());

Это лучший способ, чтобы генерировать Random цифры.


вы не должны создавать новый случайный в области метода. Сделайте его членом класса:

public class Foo {
   private Random random 

   public Foo() {
       this(System.currentTimeMillis());
   }

   public Foo(long seed) {
       this.random = new Random(seed);
   }

   public synchronized double getNext() {
        return generator.nextDouble();
   }
}

это только пример. Я не думаю, что обертывание Random этот способ добавляет никакой ценности. Поместите его в свой класс, который его использует.


Это принцип псевдо - RNG. Числа на самом деле не случайны. Они генерируются с использованием детерминированного алгоритма, но в зависимости от семени последовательность генерируемых чисел меняется. Поскольку вы всегда используете одно и то же семя, вы всегда получаете одну и ту же последовательность.


проблема в том, что вы снова засеиваете генератор случайных чисел. Каждый раз, когда вы его сеете, начальное состояние генератора случайных чисел сбрасывается, и первое случайное число, которое вы генерируете, будет первым случайным числом после начального состояния


Если вы хотите создать несколько чисел с помощью одного семени, вы можете сделать что-то вроде этого:

public double[] GenerateNumbers(long seed, int amount) {
    double[] randomList = new double[amount];
    for (int i=0;i<amount;i++) {
        Random generator = new Random(seed);
        randomList[i] = Math.abs((double) (generator.nextLong() % 0.001) * 10000);
        seed--;
    }
    return randomList;
}

он отобразит тот же список, если вы используете то же семя.


несколько примеров здесь создают новый Random экземпляр, но это лишнее. Также нет причин использовать synchronized как одно решение. Вместо этого воспользуйтесь преимуществами методов на ThreadLocalRandom класс:

double randomGenerator() {
    return ThreadLocalRandom.current().nextDouble(0.5);
}