2017-01-15 9 views
0

Мой вопрос касается Java RNG; используйте следующий код:Поселение Java RNG

for (int s = 0; s < 600; s++) { 
    Random r = new Random(s); 
    System.out.println(r.nextDouble()); 
    System.out.println(r.nextDouble() + "\n-----"); 
} 

Это приведет к генерации 600 случайных чисел. Я знаю, что это немного странно, но каждый раз в моем реальном проекте требуется новый генератор случайных чисел. Семя, которое я получаю, является последовательным. Первый случайный двойник, который генерируется, чрезвычайно близок для любого из семян, это из-за линейной конгруэнтной формулы, которая используется как инициализация?

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

Спасибо заранее

EDIT:

Позвольте мне уточнить:

int possibleRoutes = 7; 
void handlePacket(Packet p) { 

    int chosenRoute = p.hash % possibleRoutes; 
    // ...Other code... 

} 

против

int possibleRoutes = 7; 
void handlePacket(Packet p) { 

    Random r = new Random(p.hash); 
    int chosenRoute = r.nextInt() % possibleRoutes; 
    // ...Other code... 
} 

}

против

int possibleRoutes = 7; 
void handlePacket(Packet p) { 

    Random r = new Random(p.hash); 
    r.nextInt(); 
    int chosenRoute = r.nextInt() % possibleRoutes; 
    // ...Other code... 

} 

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

+1

Я не получить это использование. У государства PRNG есть состояние. Просто создайте один (за пределами, если вам нужно, в зависимости от времени) и образец в цикле. Второй вызов будет основан на другом состоянии как первом. Нет необходимости в подсевке. (повторение в пределах цикла - это плохая практика практически во всех случаях использования). Бросание проводов RNG-номера также выполняются только в очень сложных условиях и не являются подходом к преследованию здесь. – sascha

+1

Чтобы быть в безопасности: скажите нам, зачем вам нужен новый PRNG-объект в каждом цикле (если это то, что вы хотите), или если вам нужны только новые номера при каждом вызове программы. – sascha

+2

Почему вы думаете, что на каждой итерации нужен генератор случайных чисел? Подобные заявления часто отражают глубокий уровень недоразумений в отношении ПРНГ. – pjs

ответ

0

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

for (int s = 0; s < 600; s++) { 
    Random r = new Random(); 
    System.out.println(r.nextDouble()); 
    System.out.println(r.nextDouble() + "\n-----"); 
    } 

Role of seed in random number generation см

+0

Он должен быть детерминистически запущен снова –

0

вызов конструктора по умолчанию, который использует nanoTime в качестве затравки. Таким образом вам не понадобится генерировать новое семя для создания вашего объекта на каждой итерации.

//loop through number of numbers needed 
for(int i = 0; i < 100; i +) 
    //Calls default constructor 
    Random r = new Random(); 
    System.out.println(r.nextDouble()*.5); 
+1

Почему бы не повторить случайный объект? (= создание его вне цикла). Это выглядит очень неэффективно (особенно для MersenneTwister или всего, что использует огромное состояние). – sascha

+0

По моему пониманию, этот пользователь хочет перепродать каждый генерируемый номер (в котором я согласен с тобой, я бы никогда не возвращался в цикл или даже это часто). Я ухожу от этой цитаты «Мне нужен каждый генератор случайных чисел каждый раз в моем фактическом проекте " – Ryan

+0

Достаточно честный.Я не знаю, не хватает ли ему каких-то основ или если есть недоразумение. – sascha

0

Альтернатива заключается в использовании мастер случайных семян все subsiduary Randoms в петле:

Random masterRand = new Random(); 
for (int s = 0; s < 600; s++) { 
    Random r = new Random(masterRand.nextLong()); 
    System.out.println(r.nextDouble()); 
    System.out.println(r.nextDouble() + "\n-----"); 
} 
+0

Почему это лучше, чем с помощью одного «случайного» вне цикла? Оба они полностью предсказуемы, но это более запутанно и дорого. – pjs

+0

Я предположил, что вопросник требует нескольких копий «Случайный». Иногда временное сеяние может давать идентичные семена/последовательности, если петля обрабатывается достаточно быстро. Этот метод позволяет избежать этого. Кроме того, этот метод допускает повторяемость: если вы предоставите явное семя для 'masterRand', вы можете повторить точно такой же запуск семян, если хотите. Это может быть полезно для отладки и других целей. – rossum

+1

Да, но вы избегаете повторного посева и повторяемости, просто используя 'masterRand' для своих' nextDouble() 's, без лишних затрат на создание кучи одноразовых« Random's ». Все еще жду, чтобы услышать, почему OP думает, что они хотят нового генератора каждый раз ... – pjs