У вас есть идея лучше симулировать бросок монеты? - PullRequest
1 голос
/ 19 мая 2009

Прямо сейчас у меня есть

return 'Heads' if Math.random() < 0.5 

Есть ли лучший способ сделать это?

Спасибо

edit: пожалуйста, игнорируйте возвращаемое значение, и «лучше» означает точную вероятность 50-50.

Ответы [ 9 ]

9 голосов
/ 19 мая 2009

всегда мертвец просто

монета = ранд (1);

во многих языках сценариев это даст вам случайное значение int между 0 и вашим аргументом, поэтому пропуск 1 дает вам 0 или 1 (головы или хвосты).

7 голосов
/ 19 мая 2009

крошечное уважение к xkcd:

string getHeadsOrTails {
        return "heads"; //chosen by fair coin toss,
                        //guaranteed to be random
    }
7 голосов
/ 19 мая 2009

Числовые рецепты в C говорят, что не следует доверять встроенным генераторам случайных чисел, когда это важно. Вероятно, вы могли бы реализовать алгоритм, показанный в книге, как функцию ran1 (), которая, по ее утверждению, проходит все известные статистические тесты случайности (в 1992 году) менее чем за 10 8 вызовов.

Основная идея алгоритма ran1 () заключается в добавлении случайного числа к выходу генератора случайных чисел для уменьшения последовательных корреляций низкого порядка. Они используют перемешивание Бэйса-Дарема из раздела 3.2-3.3 в «Искусстве компьютерного программирования», том 2, но я предполагаю, что вы также можете использовать перемешивание Фишера-Йейтса .

Если вам нужно больше случайных значений, чем тот, этот же документ также предоставляет генератор (ran2), который должен быть хорош как минимум для 10 17 значений (мое предположение основано на периоде 2,3 x 10 18 ). Также имеется функция (ran3), которая использует другой метод для генерации случайных чисел, если линейные конгруэнтные генераторы доставят вам какую-то проблему.

Вы можете использовать любую из этих функций с тестом <0,5, чтобы быть более уверенным, что вы получаете равномерное распределение. </p>

4 голосов
/ 19 мая 2009

То, что у вас есть, это то, как я бы это сделал. Если 0.0 <= Math.random () <1.0, как стандартно, то (Math.random () <0.5) даст вам головы, когда Math.random () находится между 0.0 и 0.4999 ..., и хвосты, когда это между 0,5 и 0,999 ... Это как раз то, что вам нужно, чтобы бросить монету. </p>

Конечно, я предполагаю хорошую реализацию Math.random ().

2 голосов
/ 19 мая 2009

В системе linux вы можете читать биты из / dev / random, чтобы получить «лучшие» случайные данные, но почти случайный метод, такой как Math.Random (), подойдет практически для каждого приложения, о котором вы можете подумать если не считать серьезных криптографических работ.

0 голосов
/ 20 мая 2009

Единственный реальный ответ на этот вопрос заключается в том, что вы не можете «гарантировать» вероятность. Если вы думаете об этом, то реальная подбрасывание монеты не гарантирует 50/50 вероятности, это зависит от монеты, человека, подбрасывающего ее, и от того, брошена ли монета и катится по полу. ;)

Дело в том, что это "достаточно случайно". Если вы имитируете бросок монеты, то отправленный вами код более чем хорош.

0 голосов
/ 19 мая 2009

Я не могу комментировать посты людей, потому что у меня нет репутации, но я просто знаю, что вся тема <= vs. <рассмотрена в комментарии Билла Ящера: потому что можно эффективно предположить, что генерируется случайное любое число от 0 до 1 (что технически не так из-за ограничений размера числа с плавающей запятой, но более или менее верно на практике) не будет разницы в num <= .5 или num <.5 потому что вероятность получения любого конкретного числа в любом непрерывном диапазоне равна 0. IE: P (X = .5) = 0, когда X = случайная величина между 0 и 1. </p>

0 голосов
/ 19 мая 2009

Попробуйте различать нечетные и четные числа. Кроме того, возвращайте значение перечисления (или логическое значение) вместо строки.

0 голосов
/ 19 мая 2009

Попробуйте

return 'Heads' if Math.random() * 100 mod 2 = 0

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

...