Понимание "случайности" - PullRequest
       126

Понимание "случайности"

828 голосов
/ 18 октября 2010

Я не могу разобраться с этим, что является более случайным?

rand()

ИЛИ

rand() * rand()

Я считаю, что это настоящая головоломка для мозга, не могли бы вы помочь?меня?

РЕДАКТИРОВАТЬ:

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

Ответы [ 28 ]

1477 голосов
/ 18 октября 2010

Просто уточнение

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

Пример

Это выборка равномерного случайного распределения , смоделированная с помощью псевдослучайной переменной:

Histogram of Random()

        BarChart[BinCounts[RandomReal[{0, 1}, 50000], 0.01]]

Хотя это распределение вы получите после умножения двух случайных величин:

Histogram of Random() * Random()

        BarChart[BinCounts[Table[RandomReal[{0, 1}, 50000] * 
                                 RandomReal[{0, 1}, 50000], {50000}], 0.01]]

Итак, оба «случайны», но их распределение сильно отличается.

Другой пример

Пока 2 * Random () равномерно распределен:

Histogram of 2 * Random()

        BarChart[BinCounts[2 * RandomReal[{0, 1}, 50000], 0.01]]

Случайно () + Случайно () нет!

Histogram of Random() + Random()

        BarChart[BinCounts[Table[RandomReal[{0, 1}, 50000] + 
                                 RandomReal[{0, 1}, 50000], {50000}], 0.01]]

Центральная предельная теорема

Теорема о центральном пределе гласит, что сумма Random () стремится к нормальному распределению при увеличении членов.

Всего четыре термина:

Histogram of Random() + Random() + Random() + Random()

BarChart[BinCounts[Table[RandomReal[{0, 1}, 50000] + RandomReal[{0, 1}, 50000] +
                   Table[RandomReal[{0, 1}, 50000] + RandomReal[{0, 1}, 50000],
                   {50000}],
         0.01]]  

И здесь вы можете увидеть путь от равномерного к нормальному распределению, сложив 1, 2, 4, 6, 10 и 20 равномерно распределенных случайных величин:

Histogram of different numbers of random variables added

Редактировать

Несколько кредитов

Спасибо Томасу Але за то, что он указал в комментариях, что распределения вероятностей, показанные на последних двух изображениях, известны как распределение Ирвина-Холла

Спасибо Heike за ее замечательную torn [] функцию

151 голосов
/ 19 октября 2010

Я полагаю, что оба метода являются случайными, хотя мой читатель сказал бы, что rand() * rand() менее случайный, потому что он даст больше нулей.Как только один rand() равен 0, сумма становится 0

81 голосов
/ 18 октября 2010

Ни один из них не является «более случайным».

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

Решение вопроса о том, уменьшит ли это коллизии, ответ - нет. Это фактически увеличит коллизии из-за эффекта умножения двух чисел, где 0 < n < 1. Результатом будет меньшая доля, что приведет к смещению результата в сторону нижнего края спектра.

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

Дано начальное значение x, которое генерирует следующий список значений:

0.3, 0.6, 0.2, 0.4, 0.8, 0.1, 0.7, 0.3, ...

rand() сгенерирует приведенный выше список, а rand() * rand() сгенерирует:

0.18, 0.08, 0.08, 0.21, ...

Оба метода всегда создают один и тот же список чисел для одного и того же начального числа, и, следовательно, оракул в равной степени предсказуем. Но если вы посмотрите на результаты умножения двух вызовов, то увидите, что все они находятся под 0.3, несмотря на приличное распределение в исходной последовательности. Числа смещены из-за эффекта умножения двух фракций. Результирующее число всегда меньше, поэтому вероятность столкновения намного выше, хотя он все еще непредсказуем.

79 голосов
/ 21 октября 2010

Упрощение для иллюстрации точки.

Предположим, что ваша случайная функция выводит только 0 или 1.

random() является одним из (0,1), но random()*random() является одним из (0,0,0,1)

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


Когда я впервые опубликовал этот ответ, я хотел сделать его как можно более коротким, чтобы человек, читающий его, сразу понял разницумежду random() и random()*random(), но я не могу удержаться от ответа на первоначальный вопрос ad litteram:

Что является более случайным?

То, что random(), random()*random(), random()+random(), (random()+1)/2 или любая другая комбинация, которая не приводит к фиксированному результату, имеют один и тот же источник энтропии (или одинаковое начальное состояние в случае псевдослучайногогенераторы), ответ будет таким: равно случайным (разница в их распределении).Прекрасный пример, на который мы можем взглянуть, это игра в кости.Число, которое вы получите, будет random(1,6)+random(1,6), и мы все знаем, что получение 7 имеет наибольший шанс, но это не означает, что результат броска двух кубиков более или менее случайен, чем результат броска одного.

68 голосов
/ 18 октября 2010

Вот простой ответ.Рассмотрим монополию.Вы бросаете два шестигранных кубика (или 2d6 для тех, кто предпочитает игровую нотацию) и берете их сумму.Наиболее распространенный результат - 7, потому что есть 6 возможных способов бросить 7 (1,6 2,5 3,4 4,3 5,2 и 6,1).Тогда как 2 можно бросить только на 1,1.Легко видеть, что бросок 2d6 отличается от броска 1d12, даже если диапазон одинаков (игнорируя, что вы можете получить 1 на 1d12, точка остается неизменной).Умножение ваших результатов вместо их добавления приведет к искажению их аналогичным образом, при этом большинство ваших результатов будет находиться в середине диапазона.Если вы пытаетесь уменьшить выбросы, это хороший метод, но он не поможет сделать равномерное распределение.

(И, как ни странно, это также увеличит низкие броски. Предполагая, что ваша случайность начинается с 0вы увидите всплеск в 0, потому что он превратит любой другой бросок в 0. Рассмотрим два случайных числа от 0 до 1 (включительно) и умножение. Если какой-либо результат равен 0, все становится 0 нетне имеет значения другой результат. Единственный способ получить 1 из этого - это сделать оба броска равными 1. На практике это, вероятно, не имеет значения, но это приводит к странному графику.

53 голосов
/ 19 октября 2010

Обязательный xkcd ...
return 4; // chosen by fair dice roll, guaranteed to be random.

35 голосов
/ 19 октября 2010

Может помочь думать об этом в более дискретных числах.Подумайте, хотите ли вы генерировать случайные числа от 1 до 36, поэтому вы решаете, что самый простой способ - бросить два честных шестигранных кубика.Вы получаете это:

     1    2    3    4    5    6
  -----------------------------
1|   1    2    3    4    5    6
2|   2    4    6    8   10   12
3|   3    6    9   12   15   18
4|   4    8   12   16   20   24   
5|   5   10   15   20   25   30
6|   6   12   18   24   30   36

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

Те же принципы, которые описывают несправедливое распределение между кубиками, в равной степени применимы к числам с плавающей запятой между 0,0 и 1,0.

26 голосов
/ 18 октября 2010

Некоторые вещи о «случайности» нелогичны.

Предполагая, что плоское распределение равно rand(), вы получите неплоские распределения:

  • высокий уклон: sqrt(rand(range^2))
  • Пик смещения в середине: (rand(range) + rand(range))/2
  • низкий: смещение: range - sqrt(rand(range^2))

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

23 голосов
/ 18 октября 2010

Большинство реализаций rand () имеют некоторый период. То есть после огромного количества звонков последовательность повторяется. Последовательность выводов rand() * rand() повторяется вдвое, поэтому в этом смысле она «менее случайна».

Кроме того, без тщательного построения выполнение арифметики со случайными значениями имеет тенденцию вызывать меньшую случайность. Вышеупомянутый плакат с цитатой "rand() + rand() + rand() ..." (скажем, k раз) будет стремиться в k раз увеличить среднее значение диапазона значений rand(). (Это случайное блуждание с шагами, симметричными относительно этого среднего.)

Предположим для конкретности, что ваша функция rand () возвращает равномерно распределенное случайное действительное число в диапазоне [0,1). (Да, этот пример допускает бесконечную точность. Это не изменит результат.) Вы не выбрали конкретный язык, и разные языки могут делать разные вещи, но следующий анализ выполняется с модификациями для любой не порочной реализации rand ( ). Произведение rand() * rand() также находится в диапазоне [0,1), но больше не является равномерно распределенным. Фактически, продукт с такой же вероятностью будет в интервале [0,1 / 4), как и в интервале [1 / 4,1). Дальнейшее умножение приведет к еще большему отклонению результата к нулю. Это делает результат более предсказуемым. При широких мазках более предсказуемо == менее случайно.

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

23 голосов
/ 18 октября 2010

«случайный» против «более случайный» немного похож на вопрос, какой ноль больше zero'y.

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

Истинный RNG крипто-типа на самом деле будет случайным. И запуск значений через какую-либо функцию не может добавить к ней больше энтропии и, скорее всего, может удалить энтропию, сделав ее более случайной.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...