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

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

rand()

ИЛИ

rand() * rand()

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

EDIT:

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

809
задан Trufa 18 окт. '10 в 6:40
источник поделиться

27 ответов

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

Хотя предыдущие ответы правильны, когда вы пытаетесь определить случайность псевдослучайной переменной или ее умножения, вы должны знать, что, хотя Random() обычно равномерно распределяется, 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

Edit

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

Благодаря Thomas Ahle для указания в комментариях, что распределения вероятностей, показанные на двух последних изображениях, известны как Распределение Ирвин-Холла

Благодаря Heike за ее замечательную функцию torn []

1455
ответ дан Dr. belisarius 18 окт. '10 в 7:03
источник поделиться

Мой ответ на все вопросы случайных чисел - это alt text

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

151
ответ дан Janco 18 окт. '10 в 23:32
источник поделиться

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

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, несмотря на приличное распределение в исходной последовательности. Числа являются предвзятыми из-за эффекта умножения двух фракций. Получающееся число всегда меньше, поэтому гораздо вероятнее будет столкновение, несмотря на то, что оно все еще столь же непредсказуемо.

80
ответ дан Matthew Scharley 18 окт. '10 в 6:45
источник поделиться

Облегчение для иллюстрации точки.

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

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

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


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

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

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

77
ответ дан Alin Purcaru 21 окт. '10 в 1:43
источник поделиться

Вот простой ответ. Рассмотрим Монополию. Вы бросаете две шестисторонние кости (или 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. На практике это, вероятно, неважно, но это создает странный график.)

67
ответ дан valadil 18 окт. '10 в 18:31
источник поделиться

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

51
ответ дан crowne 18 окт. '10 в 23:36
источник поделиться

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

     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.

34
ответ дан Juliet 18 окт. '10 в 23:25
источник поделиться

Некоторые вещи о "случайности" противоречат интуиции.

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

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

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

26
ответ дан staticsan 18 окт. '10 в 7:03
источник поделиться

"random" vs. "more random" - это немного похоже на вопрос, какой Zero больше нуля.

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

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

24
ответ дан abelenky 18 окт. '10 в 6:45
источник поделиться

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

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

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

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

23
ответ дан Eric Towers 18 окт. '10 в 7:10
источник поделиться

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

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

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

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

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

18
ответ дан PachydermPuncher 18 окт. '10 в 22:01
источник поделиться

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

Самый простой способ думать об теории информации - это наименьшая единица информации, один бит.

В стандартной библиотеке C rand() возвращает целое число в диапазоне от 0 до RAND_MAX, ограничение, которое может быть определено по-разному в зависимости от платформы. Предположим, что RAND_MAX определяется как 2^n - 1, где n - некоторое целое число (это случается в реализации Microsoft, где n равно 15). Тогда мы бы сказали, что хорошая реализация вернет n бит информации.

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

Независимость бит гарантирует, что числа, представленные партиями бит, будут равномерно распределены по их диапазону. Это интуитивно очевидно: если имеется 15 бит, допустимый диапазон равен нулю до 2^15 - 1= 32767. Каждое число в этом диапазоне является уникальным паттерном бит, например:

010110101110010

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

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

Возвращаясь к исходному предложению, предположим, что вы хотите перейти от партий по 15 к партиям по 30, попросите rand() для первого номера, сдвиньте бит на 15 мест, затем добавьте к нему еще rand(). Это способ объединить два вызова в rand(), не нарушая равномерного распределения. Он работает просто потому, что между местоположениями, где вы размещаете бит информации, нет совпадений.

Это сильно отличается от "растяжения" диапазона rand() путем умножения на константу. Например, если вы хотите удвоить диапазон rand(), вы можете умножить на два, но теперь вы получите только цифры и никогда нечетные числа! Это не совсем ровное распределение и может быть серьезной проблемой в зависимости от приложения, например. игра в рулетку, предположительно позволяющая нечетные/четные ставки. (Подумав о битах, вы избегаете этой ошибки интуитивно, потому что вы поймете, что умножение на два - это то же самое, что смещение битов влево (большее значение) на одно место и заполнение пробела нулем. Таким образом, очевидно, что объем информации одинаков - он немного переместился.)

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

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

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

12
ответ дан Daniel Earwicker 19 окт. '10 в 15:02
источник поделиться

Как говорили другие, легкий короткий ответ: Нет, он не более случайный, но он меняет распределение.

Предположим, вы играли в игру в кости. У вас есть совершенно честные случайные кости. Будет ли бросок кубика "более случайным", если перед каждым броском броска вы сначала кладете две кости в миску, встряхиваете ее, выбираете одну из кубиков наугад, а затем переворачиваете ее? Ясно, что это не имеет значения. Если обе кости дают случайные числа, то случайный выбор одной из двух кубиков не будет иметь никакого значения. В любом случае вы получите случайное число от 1 до 6 с равномерным распределением по достаточному количеству рулонов.

Я полагаю, что в реальной жизни такая процедура может быть полезна, если вы подозреваете, что кости не могут быть честными. Если, скажем, кости немного неуравновешенны, поэтому один имеет тенденцию давать 1 чаще, чем 1/6 времени, а другой, как правило, дает 6 необычно часто, тогда случайный выбор между ними будет затенять смещение. (Хотя в этом случае 1 и 6 все равно появятся более 2, 3, 4 и 5. Ну, я думаю, в зависимости от характера дисбаланса.)

Существует множество определений случайности. Одно определение случайного ряда состоит в том, что оно представляет собой ряд чисел, создаваемых случайным процессом. По этому определению, если я скачу честную смерть 5 раз и получаю числа 2, 4, 3, 2, 5, это случайная серия. Если я затем прокручу ту же самую честную смерть еще 5 раз и получаю 1, 1, 1, 1, 1, то это также случайная серия.

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

ИЗМЕНИТЬ

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

Для тех, кто не читал ссылку "Велизарий", суть заключается в следующем: игроку, предлагающему игру, предоставляется выбор из 3-х дверей. За одним из них стоит ценный приз, за ​​другим - что-то бесполезное. Он выбирает дверь №1. Прежде чем выявить, является ли он победителем или проигравшим, хозяин открывает дверь №3, чтобы показать, что это проигравший. Затем он дает сопернику возможность переключиться на дверь №2. Должен ли участник делать это или нет?

Ответ, который оскорбляет интуицию многих людей, заключается в том, что он должен переключиться. Вероятность того, что его первоначальный выбор был победителем, - 1/3, что вторая дверь - победитель 2/3. Моя первоначальная интуиция, как и у многих других людей, заключается в том, что не будет никакой выгоды при переключении, что шансы только что были изменены до 50:50.

В конце концов, предположим, что кто-то включил телевизор сразу после того, как хозяин открыл проигрышную дверь. Этот человек увидит две оставшиеся закрытые двери. Предполагая, что он знает природу игры, он скажет, что у каждой двери скрывается шанс 1/2. Как шансы для зрителя равны 1/2: 1/2, в то время как шансы для участника равны 1/3: 2/3?

Мне действительно нужно было подумать об этом, чтобы превзойти мою интуицию. Чтобы понять это, поймите, что, когда мы говорим о вероятностях в подобной проблеме, мы имеем в виду вероятность, которую вы назначили с учетом доступной информации. Члену экипажа, который поместил приз, скажем, дверь №1, вероятность того, что выигрыш за дверью №1 составляет 100%, а вероятность того, что она стоит за любой из двух других дверей, равна нулю.

Коэффициенты члена команды отличаются от шансов участника, потому что он знает что-то, чего не имеет участник, а именно, какую дверь он поставил. Аналогично, шансы участника отличаются от шансов зрителя, потому что он знает то, чего не видит зритель, а именно, какую дверь он первоначально выбрал. Это не имеет значения, потому что выбор хоста, который открывает дверь, не является случайным. Он не откроет дверь, которую выбрал соперник, и он не откроет дверь, которая скрывает приз. Если это одна и та же дверь, это оставляет ему два выбора. Если у них разные двери, это оставляет только один.

Итак, как мы получаем 1/3 и 2/3? Когда участник первоначально выбрал дверь, у него была 1/3 вероятность набрать победителя. Я думаю, что многое очевидно. Это означает, что был шанс 2/3, что одна из других дверей является победителем. Если в игре хозяев появилась возможность переключаться без дополнительной информации, то не было бы никакой выгоды. Опять же, это должно быть очевидно. Но один из способов взглянуть на это - сказать, что есть шанс 2/3, который он выиграет, переключившись. Но у него есть 2 альтернативы. Таким образом, каждый из них имеет только 2/3, деленный на 2 = 1/3 шанс стать победителем, что не лучше его первоначального выбора. Конечно, мы уже знали конечный результат, это просто вычисляет его по-другому.

Но теперь хозяин показывает, что один из этих двух вариантов не победитель. Таким образом, шанс 2/3, что дверь, которую он не выбрал, является победителем, теперь он знает, что 1 из 2 альтернатив - не так. Другой может быть или не быть. Таким образом, он больше не имеет 2/3 деления на 2. У него есть ноль для открытой двери и 2/3 для закрытой двери.

12
ответ дан Jay 19 окт. '10 в 0:25
источник поделиться

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

rand() mod 2

При достаточно большом распределении число четных чисел должно равняться числу нечетных чисел.

Теперь рассмотрим небольшую настройку:

rand() * rand() mod 2

Если один из результатов четный, то весь результат должен быть четным. Рассмотрим 4 возможных результата (даже * четный = четный, четный * нечетный = четный, нечетный * четный = четный, нечетный * нечетный = нечетный). Теперь, при достаточно большом распределении, ответ должен быть даже в 75% случаев.

Я бы поставил головы, если бы я был вами.

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

11
ответ дан user479885 19 окт. '10 в 2:13
источник поделиться

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

В ситуации ОП он хочет знать, каков результат X * X = X ^ 2, где X - случайная величина, распределенная вдоль Uniform [0,1]. Мы будем использовать метод CDF, поскольку это просто сопоставление "один к одному".

Так как X ~ Uniform [0,1], то cdf: f X (x) = 1 Нам нужно преобразование Y < - X ^ 2, таким образом, y = x ^ 2 Найти обратное x (y): sqrt (y) = x, это дает нам x как функцию y. Затем найдите производную dx/dy: d/dy (sqrt (y)) = 1/(2 sqrt (y))

Распределение Y задается как: f Y (y) = f X (x (y)) | dx/dy | = 1/(2 sqrt (y))

Мы еще не закончили, мы должны получить домен Y., так как 0 <= x < 1, 0 <= x ^ 2 < 1 поэтому Y находится в диапазоне [0, 1). Если вы хотите проверить, действительно ли pdf файл Y является pdf, интегрируйте его по домену: Интегрируйте 1/(2 sqrt (y)) от 0 до 1, и действительно, он появляется как 1. Также обратите внимание, что форма указанной функции выглядит так, как это было написано.

Что касается таких вещей, как X 1 + X 2 +... + X n, (где X i ~ Uniform [0,1]), мы можем просто обратиться к Центральной предельной теореме, которая работает для любого распределения, моменты которого существуют. Вот почему на самом деле существует Z-тест.

Другие методы определения полученного pdf включают преобразование якобиана (которое является обобщенной версией метода cdf) и метод MGF.

EDIT: В качестве пояснения обратите внимание, что я говорю о распределении полученного преобразования, а не о его случайности. Это на самом деле для отдельного обсуждения. И то, что я на самом деле получил, было для (rand()) ^ 2. Для rand() * rand() это намного сложнее, что в любом случае не приведет к равномерному распределению любых видов.

10
ответ дан Wil 18 окт. '10 в 17:02
источник поделиться

Это не совсем очевидно, но rand() обычно более случайный, чем rand()*rand(). Важно то, что это не очень важно для большинства применений.

Но, во-первых, они производят разные распределения. Это не проблема, если это то, что вы хотите, но это имеет значение. Если вам нужен конкретный дистрибутив, тогда игнорируйте весь "более случайный" вопрос. Итак, почему rand() более случайный?

Ядро причины rand() более случайное (в предположении, что он производит случайные числа с плавающей запятой с диапазоном [0..1], что очень распространено) заключается в том, что когда вы умножаете два числа FP вместе с большим количеством информации в мантиссе, вы получаете некоторую потерю информации с самого конца; там не достаточно бит в IEEE с двойной точностью, чтобы хранить всю информацию, которая была в двух платах с двойной точностью IEEE, равномерно случайно выбранных из [0..1], и эти лишние биты информации теряются. Конечно, это не так важно, поскольку вы (вероятно) не собираетесь использовать эту информацию, но потеря реальна. Также не имеет значения, какое распределение вы производите (т.е. Какую операцию вы используете для выполнения комбинации). Каждое из этих случайных чисел имеет (в лучшем случае) 52 бита случайной информации - то, что может содержать двойной бит IEEE, и если вы объедините два или более в одном, вы все равно ограничены наличием не более 52 бит случайной информации.

В большинстве случаев использование случайных чисел не используется даже близко к такой же случайности, сколько фактически доступно в случайном источнике. Получите хороший PRNG и не волнуйтесь об этом слишком много. (Уровень "доброты" зависит от того, что вы делаете с ним, вы должны быть осторожны при моделировании или криптографии в Монте-Карло, но в противном случае вы, вероятно, можете использовать стандартный PRNG, как это обычно гораздо быстрее.)

9
ответ дан Donal Fellows 19 окт. '10 в 13:51
источник поделиться

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

Если на дисплее вашего компьютера отображается 16 цифр rand(), скажем, 0.1234567890123 умноженное на второй rand(), 0.1234567890123, даст 0.0152415 что-то вы бы определенно нашли меньше решений, если бы повторили эксперимент 10 ^ 14 раз.

7
ответ дан Huub 19 окт. '10 в 13:17
источник поделиться

Плавающие рандомы основаны, в общем, на алгоритме, который производит целое число от нуля до некоторого диапазона. Таким образом, используя rand() * rand(), вы по существу говорите, что int_rand() * int_rand()/rand_max ^ 2 - означает, что вы исключаете любое простое число /rand _max ^ 2.

Это значительно меняет рандомизированное распределение.

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

7
ответ дан Fordi 18 окт. '10 в 8:38
источник поделиться

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

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

Другими словами, поскольку мы должны ограничить случайный вызов между 0 и X (X - предел размера нашей переменной), мы будем иметь группу "случайных" чисел между 0 и X.

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

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

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

Скажем, например, RandomReal({-x, x}, 50000, .01), тогда вы получите равномерное распределение чисел на отрицательной положительной стороне, и если бы вы добавили случайные числа вместе, они сохранили бы свою "случайность".

Теперь я не уверен, что произойдет с Random() * Random() с отрицательным до положительного диапазона... это будет интересный график, чтобы увидеть... но мне нужно вернуться к написанию кода сейчас.:-P

3
ответ дан user479538 18 окт. '10 в 19:47
источник поделиться
  • Нет такой вещи, как более случайный. Он случайный или нет. Случайное означает "трудно предсказать". Это не означает недетерминированности. Как случайные(), так и случайные() * random() одинаково случайны, если случайный() случайный. Распределение не имеет значения, насколько случайность идет. Если происходит неравномерное распределение, это означает, что некоторые значения более вероятны, чем другие; они все еще непредсказуемы.

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

  • Важные значения случайных чисел важны: повторяемость и воспроизводимость, статистическая случайность, (обычно) равномерно распределенная, а большой период - несколько.

  • Относительно преобразований на случайных числах: Как сказал кто-то, сумма двух или более равномерно распределенных результатов в нормальном распределении. Это аддитивная центральная предельная теорема. Он применяется независимо от распределения источника, если все распределения независимы и идентичны. Мультипликативная центральная предельная теорема говорит, что произведение двух или более независимых и indentically-распределенных случайных величин является логнормальным. Граф, созданный кем-то другим, выглядит экспоненциально, но он действительно логнормален. Итак, random() * random() логарифмически распределен (хотя он не может быть независимым, поскольку числа вытягиваются из одного потока). Это может быть желательно в некоторых приложениях. Однако обычно лучше генерировать одно случайное число и преобразовывать его в логарифмически распределенное число. Случайное() * random() может быть сложно проанализировать.

За дополнительной информацией обратитесь к моей книге на сайте www.performorama.org. Книга находится в стадии разработки, но имеется соответствующий материал. Обратите внимание, что номера разделов и разделов могут меняться со временем. Глава 8 (теория вероятностей) - разделы 8.3.1 и 8.3.3, глава 10 (случайные числа).

2
ответ дан Tom 02 июня '11 в 21:15
источник поделиться

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

1
ответ дан HamoriZ 25 мая '12 в 12:46
источник поделиться

Собственно, когда вы думаете об этом rand() * rand() меньше, чем rand(). Вот почему.

По существу, число четных чисел равно числу четных чисел. И говоря, что 0.04325 нечетно, и, как и 0,388, четный, а 0,4 четный, а 0,15 - нечетный,

Это означает, что rand() имеет равный шанс быть четным или нечетным десятичным.

С другой стороны, rand() * rand() имеет шансы укладываться несколько иначе. Допустим:

double a = rand();
double b = rand();
double c = a * b;

a и b оба имеют 50% -ный шанс получения четности или нечетности. Зная, что

  • even * even = even
  • even * odd = even
  • нечетный * нечетный = нечетный
  • нечетный * четный = четный

означает, что 75% шанс, что c является четным, а только 25% шанс нечетным, что делает значение rand() * rand() более предсказуемым, чем rand(), поэтому менее случайным.

0
ответ дан John S. 15 янв. '16 в 20:36
источник поделиться

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

В результате будет последовательность из 2 ^ n псевдослучайных чисел, т.е. ни одна из них не повторяется в последовательности, где n - количество бит в LFSR.... что приводит к равномерному распределению.

http://en.wikipedia.org/wiki/Linear_feedback_shift_register http://www.xilinx.com/support/documentation/application_notes/xapp052.pdf

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

Например, 32-разрядный LFSR будет генерировать 2 ^ 32 уникальных номера в последовательности (нет 2 одинаковых), начиная с данного семени. Последовательность всегда будет в том же порядке, но исходная точка будет отличаться (очевидно) для разных семян. Таким образом, если возможная повторяющаяся последовательность между посевами не является проблемой, это может быть хорошим выбором.

Я использовал 128-битный LFSR для генерации случайных тестов в аппаратных симуляторах, используя семя, которое является результатом md5 при постоянно меняющихся системных данных.

0
ответ дан johnny 02 июня '11 в 18:37
источник поделиться

Легко показать, что сумма двух случайных чисел не обязательно случайна. Представьте, что у вас есть шестигранный кубик. У каждого номера есть шанс на 1/6. Теперь скажите, что у вас было 2 кубика и суммировал результат. Распределение этих сумм не 1/12. Зачем? Потому что некоторые цифры больше, чем другие. Есть несколько разделов из них. Например, число 2 является суммой только 1 + 1, но 7 может быть сформировано 3 + 4 или 4 + 3 или 5 + 2 и т.д., Поэтому у него больше шансов на выход.

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

-1
ответ дан sashang 26 сент. '11 в 7:20
источник поделиться

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

Генераторы случайных чисел - это устройства (в очень общем смысле), которые имеют несколько характеристик, которые могут быть изменены для достижения цели. Некоторые из них (от меня):

  • Энтропия: как в энтропии Шеннона
  • Распространение: статистическое распределение (пуассон, нормальное и т.д.)
  • Тип: что является источником чисел (алгоритм, естественное событие, комбинация и т.д.) и применяемый алгоритм.
  • Эффективность: быстрота или сложность исполнения.
  • Шаблоны: периодичность, последовательности, прогоны и т.д.
  • и, возможно, больше...

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

-1
ответ дан Loki 02 июня '11 в 16:51
источник поделиться

Как уже указывали другие, этот вопрос трудно ответить, поскольку каждый из нас имеет свою собственную картину случайности в своей голове.

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

Чтобы вернуться к реальному вопросу. В этом термина нет более или менее случайного:

появляются только случайные!

В обоих случаях - просто rand() или rand() * rand() - ситуация та же: После нескольких миллиардов чисел последовательность будет повторяться (!). Он появляется случайным образом для наблюдателя, потому что он не знает всей последовательности, но на компьютере нет истинного случайного источника, поэтому он также не может создать случайность.

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

-1
ответ дан Fabian Bigler 17 мая '13 в 23:26
источник поделиться

Ответ будет, это зависит, надеюсь, что rand() * rand() будет более случайным, чем rand(), но как:

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

Хорошо, если вы проверите любое из этих выше, я предлагаю вам перейти к простому "rand()". Поскольку ваш код будет более доступен для чтения (не спрашивал себя, почему вы это сделали, для... ну... более 2 секунд), легко поддерживать (если вы хотите заменить вас rand с супер_rand).

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

-2
ответ дан dvhh 18 окт. '10 в 9:54
источник поделиться

Другие вопросы по меткам