Как случайным является Math.random() в java на разных jvms или разных машинах

У меня есть большая распределенная программа на многих разных физических серверах, каждая программа генерирует множество потоков, каждый поток использует Math.random() в своих операциях, чтобы нарисовать часть из множества общих пулов ресурсов.

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

Есть ли что-то, что лучше, чем Math.random() и работает так же хорошо (не намного хуже)?

Ответ 1

Math.random() основан на java.util.Random, который основан на линейном конгруэнтном генераторе . Это означает, что его случайность не идеальна, но достаточно хороша для большинства задач, и кажется, что этого должно быть достаточно для вашей задачи.

Однако, похоже, вы используете возвращаемое значение double Math.random() для выбора между фиксированным количеством вариантов, что может еще больше ухудшить качество случайности. Лучше использовать java.util.Random.nextInt() - просто повторите использование одного и того же объекта Random.

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

Наши мозги действительно хороши в определении шаблонов в идеальной случайности, поэтому это означает почти ничего.

Ответ 2

Алгоритм Math.Random "достаточно случайный" для любой платформы. Математическая модель, используемая для создания псевдо-случайных чисел, является хорошей. Это зависит от того, сколько потоков вы используете. Для чего угодно, кроме действительно большого количества потоков, это не даст вам даже распределения (характер случайных чисел), а затем Math.random() даст вам много накладных расходов.

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

Ответ 3

Этот поток может быть полезен: Насколько хорошо java.util.Random?

другие варианты:

  • генерировать случайное семя при инициализации случайного экземпляра
  • если вы используете linux use/dev/urandom

Ответ 4

В javadoc Math.random() это просто простой способ использования java.util.Random. Это сказало это просто псевдослучайный алгоритм. Простым способом проверки того, насколько случайным является алгоритм, является рисование случайных точек на сетке x/y. Вы не должны находить никаких шаблонов.

Чтобы получить реальные номера ramdom, вы можете использовать такие сервисы, как http://www.random.org. Если это нужно замедлить, возможно, регулярно называть его семенами java.util.Random может приблизить вас к истинному случайному.