Подтвердить что ты не робот

Случайный класс действует нечетно?

В этом коде:

Random random = new Random(441287210);
for(int i=0;i<10;i++)
    System.out.print(random.nextInt(10)+" ");
}

Выходной сигнал 1 1 1 1 1 1 1 1 1 1, каждый раз.

Почему это? Разве не Random должен быть... ну... случайным? Я думал, что класс Random использует System.nanoTime, поэтому вывод должен быть в целом случайным. Может кто-нибудь объяснить?

4b9b3361

Ответ 1

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

Здесь вы используете постоянное начальное значение, которое не изменяется между исполнением вашего кода. Поэтому вы всегда получаете одну и ту же последовательность. Просто случается, что эта последовательность 1 1 1 1 1 1 ... для этого конкретного семени.

Ответ 2

Пусть он напечатает еще пару, первые 100 -

1 1 1 1 1 1 1 1 1 1 3 4 7 2 2 6 0 3 0 2 8 4 1 6 0 0 0 2 8 2 9 8 9 2 5 2 1 1 4 5 3 4 1 4 1
8 7 6 6 0 6 5 0 4 5 5 6 0 8 3 8 9 7 4 0 9 9 7 7 9 3 9 6 4 5 0 6 3 7 4 9 8 7 6 2 8 9 8 4 4
8 4 9 0 1 6 9 6 1 5

который выглядит нормально.

Каждая хорошая (псевдо) случайная последовательность содержит полосы повторяющихся чисел, эта начинается с одной.

Ответ 3

Нечего сказать, что последовательность из 10 1 в строке невозможна. Тот, кто дал вам начальное значение 441287210, просто обнаружил такое значение, которое начинается с 10 1 в строке. Если вы продолжаете называть nextInt() (т.е. Более 10 раз), вы увидите случайные значения. Должно быть возможно найти другие значения семян, которые приведут к другим "явно неслучайным" последовательностям.

Ответ 4

Random - линейный конгруэнтный генератор ; т.е. он основан на формуле вида:

N <- (N * C1 + C2) % M

где C1, C2 и M - константы.

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

Ваша тестовая программа эффективно взяла 10 последовательных чисел от базового генератора, рассчитала их значение по модулю 10... и обнаружила, что они все одинаковы. Фактически, по модулю 10 "резонирует" с естественной периодичностью генератора... за короткий промежуток времени.

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


Примечания:

  • Случайный не является генератором случайных чисел. Это генератор псевдослучайных чисел. Это означает, что если вы знаете начальное состояние, генерируемые числа полностью предсказуемы.
  • Использование истинного случайного семени для Random не помогает. Это просто затрудняет воспроизведение проблемы.
  • Скорее всего, будут другие семена для Random, которые предоставят вам похожие шаблоны с этим конкретным тестом.
  • С чисто математической точки зрения десять из них не более или менее "случайны", чем любая другая последовательность из десяти чисел. Но с математической точки зрения, Random не является случайным вообще. Фактически, это полностью предсказуемо, если вы выяснили, что такое текущее значение N. Проблема состоит в том, что автокорреляция, которая делает последовательность, выглядит интуитивно неслучайной.
  • Если вы хотите избежать такой интуитивной неслучайности, используйте SecureRandom, который должен быть либо истинным источником случайных чисел, либо генератором псевдослучайных чисел, которые намного сложнее предсказать.

Ответ 5

Если вы используете for(int i=0;i<100;i++), выведенная последовательность будет "более случайной". Вероятность случайной последовательности из десяти 1 по очереди может быть небольшой, но это не невозможно. (Поскольку при наличии достаточного количества выборок любая последовательность почти наверняка встречается.)

Это просто интересное совпадение.

Ответ 6

Случайный класс использует seed, чтобы генерировать случайное число при вызове nextInt() и рекомендуется, чтобы оно было длинным, когда вы создаете случайный объект, вы предоставляете int, которого недостаточно для случайности.

Попробуйте запустить цикл в 20 раз, вы увидите случайность или удалите семя или получите очень длинное начальное значение