В классе java есть случайный экземпляр, который используется двумя методами.

public class Utils{
    Random rand = new Random();

    public double nextGaussian1(){
          return rand.nextGaussian();
    }

    public double nextGaussian2(){
          return rand.nextGaussian();
    }   
}

Могу ли я использовать только один случайный экземпляр для получения гауссовских распределений из двух методов?

0
Andrei N 25 Дек 2013 в 13:59

2 ответа

Лучший ответ

Да, вы можете использовать один экземпляр Random. Поддерживающая реализация для nextGaussian() - это полярный метод Бокса, Мюллера и Марсальи, который генерирует гауссианы попарно. Первый вызов сгенерирует пару и вернет первое из двух значений, следующий вызов просто вернет ранее сгенерированное второе значение. Пары математически независимы (*) , если одинаковы входные данные. Теоретически это может быть проблемой, если формы поступают из линейного конгруэнтного генератора с плохой структурой решетки, но Java LCG довольно приличный, и на практике результаты можно считать фактически независимыми для большинства применений.

Более важный вопрос был бы в том, зачем вам нужны два разных метода, чтобы быть источниками гауссианов? Что это дает тебе, чего не достичь просто звонком rand.nextGaussian()?

(*) - возвращаемые значения Гаусса являются синусоидальными и косинусными компонентами вектора, созданного в полярных координатах, и поэтому ортогональны. Для гауссианов ортогональность подразумевает независимость.

1
pjs 26 Дек 2013 в 07:39

Если два метода вызываются случайным образом, это нормально, однако, если вы вызываете их по шаблону, подобному следующему, он не будет работать так, как задумано, поскольку он генерирует пары гауссовых чисел.

for(int i = 0; i < 100; i++ ) {
    values1[i] = Utils.nextGaussian1();
    values2[i] = Utils.nextGaussian2();
}

Это та же проблема, что и

Random rand = new Random();
for(int i = 0; i < 100; i++ ) {
    values1[i] = rand.nextGaussian();
    values2[i] = rand.nextGaussian();
}

Кстати, простой способ создать служебный класс - использовать enum без экземпляров

public enum Utils {;
     // class is final with a private constructor

     public static double nextGaussian() {
          return random.nextGaussian();
     }
}
0
Peter Lawrey 25 Дек 2013 в 21:57