2013-12-25 4 views
0

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

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

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

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

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

ответ

1

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

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

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

+0

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

0

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

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(); 
} 

BTW простой способ сделать вспомогательный класс заключается в использовании enum без каких-либо случаях

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

    public static double nextGaussian() { 
      return random.nextGaussian(); 
    } 
} 
+0

Где я могу узнать, почему «пары гауссовских чисел» не являются гауссовскими числами? BTW Это простой, но семантически неправильный способ создания класса полезности. Методы должны быть статическими. ;) –

+0

@skydreamerr Вы можете прочитать код, чтобы увидеть, что каждое второе значение изменено для обеспечения гауссовского распространения. Я не вижу проблемы с использованием статических методов в 'enum'. Что вы подразумеваете под «семантически неправильным способом»? –

+0

Enum означает перечисление. Enum не предназначен для класса полезности для языковых разработчиков. Это похоже на трюк, и это может запутать разработчиков. –

Смежные вопросы