Случайность Java всегда возвращает тот же номер, когда я устанавливаю семя?

Мне нужна помощь с генератором случайных чисел, который я создаю. Мой код выглядит следующим образом (внутри classа, называемого номерами):

public int random(int i){ Random randnum = new Random(); randnum.setSeed(123456789); return randnum.nextInt(i); } 

Когда я вызываю этот метод из другого classа (чтобы создать случайное число), он всегда возвращает тот же номер. Например, если я должен был сделать:

 System.out.println(numbers.random(10)); System.out.print(numbers.random(10)); 

он всегда печатает тот же номер, например 5 5. Что мне нужно сделать, чтобы он печатал два разных числа, например 5 8

Обязательно, чтобы я установил семя.

благодаря

Вам нужно разделить экземпляр Random() по всему classу:

 public class Numbers { Random randnum; public Numbers() { randnum = new Random(); randnum.setSeed(123456789); } public int random(int i){ return randnum.nextInt(i); } } 

Если вы всегда задаете семя, вы всегда получите тот же ответ. Это то, что устанавливает семя.

Есть две проблемы, вызывающие то, что вы видите. Во-первых, код устанавливает начальное значение для экземпляра Random. Во-вторых, метод экземпляра «случайный» создает новый случайный объект, а затем сразу же устанавливает его семя с одним и тем же семенем каждый раз. Сочетание этих двух гарантий, что при одном и том же значении i метод «случайный» всегда будет возвращать одно и то же значение, и он всегда будет первым в последовательности, которую семя всегда генерирует.

Предполагая, что установка семени является обязательной, чтобы получить следующее значение в последовательности, а не одно и то же первое значение последовательности каждый раз, экземпляр randnum из Random не может иметь свой набор семян каждый раз непосредственно перед вызовом следующего метода. Чтобы исправить это, переместите экземпляр локальной переменной randnum из Random из области действия метода случайного экземпляра в область classа. Во-вторых, установите семя только тогда, когда случайному назначается случайный экземпляр или только для получения той же последовательности результатов от него, чтобы начать заново. Метод экземпляра classа RandomSeries (long seed) не может выполняться в области видимости classа, поэтому конструктор должен установить его с помощью конструктора Random с параметром long seed. Следующий код показывает изменения:

 public class RandomDemo { // arbitrary example class name // lots of class related stuff may be here... // still inside the class scope... // private is a good idea unless an external method needs to change it private Random randnum = new Random(123456789L); // the seed guarantees it will always produce the same sequence // of pseudo-random values when the next methods get called // for unpredicable sequences, use the following constructor instead: // private Random randnum = new Random(); // lots of code may be here... // publicly exposed instance method for getting random number // from a sequence determined by seed 123456789L // in the range from 0 through i-1 public int randnum(int i) { // don't set the seed in here, or randnum will return the exact same integer // for the same value of i on every method call // nextInt(i) will give the next value from randnum conforming to range i return randnum.nextInt(i); } // end randnum // lots of more code may be here... } // end class RandDemo 

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

Если это для проекта classа или тестирования программного обеспечения, где последовательность должна быть предсказуемой и повторяемой, установка семени в фиксированное значение имеет смысл. В противном случае задайте вопрос о правильности установки семени на некоторое заданное значение. Ниже объясняется больше о Random, семенах для Random и почему существует условие для предоставления семени.

Random имеет два конструктора:

 Random() 

а также

 Random(long seed) 

и метод экземпляра

 setSeed(long seed) 

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

 setSeed(long seed) 

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

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

Параметры семени Random заданы так, чтобы можно было случайным объектом создать последовательность, которая повторяется. Для данного семени последовательность значений в следующих методах гарантированно будет одной и той же последовательностью всякий раз, когда используется это семя. Это полезно для тестирования программного обеспечения, которое будет использовать псевдослучайные последовательности, где результаты должны быть предсказуемыми и повторяемыми. Это не полезно для создания различных непредсказуемых псевдослучайных последовательностей в работе.

Утверждение «обязательно, чтобы я установил семя» отрицает любую непредсказуемость псевдослучайных последовательностей Случайного объекта. Это для проекта classа или теста программного обеспечения, где результаты должны быть одинаковыми для одних и тех же входных данных для программы?

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

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

Вам обязательно нужно создать new Random() внутри вашего random(int i) метода random(int i) ? Если вы ОБЯЗАТЕЛЬНЫ, чтобы сделать это таким образом, вы могли бы использовать, вы могли бы установить семя на текущее время, хотя это не подлежит проверке, потому что вы могли бы называть свои номера. numbers.random(10) так быстро после другого, что он в конечном итоге это одно и то же семя. Вы можете попробовать, возможно, использовать nanoSeconds (System.nanoTime (), я думаю? И если setSeed принимает только int, умножьте его, я думаю).

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

Наконец, последняя проблема может заключаться в том, что вы одновременно объявляете несколько classов number . Все они будут иметь одинаковое случайное семя и дают вам один и тот же набор случайных чисел. Если это произойдет, вы можете создать static Random в своем основном classе и вызвать его в своем classе чисел. Это будет сопрягать эти два classа, хотя, но это сработает. Другой вариант – отправить инкрементное значение вашему конструктору номерного number , для каждого number вы инициируете, и использовать значение, которое вы передаете в качестве семени.

Второй вариант должен быть хорош для вас, хотя, если вам разрешено это делать.

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

Если вы не поместите семя, то первое семя будет взято из источника переменной (обычно это системное время).

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

  • Как создать случайную буквенно-цифровую строку в C ++?
  • Случайное целое число в VB.NET
  • Алгоритм произвольного участка
  • Выбор случайного элемента из набора
  • Какое распределение вы получаете от этой случайной случайной перетасовки?
  • Как я засеваю случайный class, чтобы избежать дублирования случайных значений
  • Уникальное генерирование случайных строк
  • Генератор случайных чисел генерирует только одно случайное число
  • Math.random () против Random.nextInt (int)
  • linq: порядок по случайным
  • Как генерировать случайные целые числа в определенном диапазоне в Java?
  • Interesting Posts

    Как сообщить CMake ссылку в статической библиотеке в исходном каталоге?

    Неподдерживаемый аддон Firefox

    Преобразование нескольких строк в один с запятой как разделитель

    Есть ли что-то вроде «универсального приемника 2,4 ГГц» для беспроводных периферийных устройств?

    Блокировать сайт в Windows без файла хоста

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

    mongodb найти несколько элементов массива

    Как преобразовать строку в массив char в C ++?

    Как получить список зарегистрированных пользователей / подключенных пользователей в .NET?

    В чем разница между «?», «E» и «T» для Java-дженериков?

    Преобразование строки в массив int с использованием LINQ

    Могут ли комментарии использоваться в JSON?

    Получение десугатной части выражения Scala для / понимания?

    Поддержка контроля версий в Microsoft Word 2007

    Как печатать форматированные значения BigDecimal?

    Давайте будем гением компьютера.