Вопрос по random, c – Мне нужно генерировать случайные числа в C [дубликат]

4

Possible Duplicates:
How to generate a random number in C?
implementation of rand()
Generating random terrain in Blender3D

Мне нужны качественные случайные числа в Си, но я понятия не имею, что на самом деле делать. Мне нужно, чтобы можно было получить цифры от 1 до 100. Любая помощь или, возможно, указать мне, где я могу найти помощь.

Не дубликат ИМО. Ни в одном из этих вопросов не упоминается требование о том, чтобы выходные данные были неотличимы от случайных. Теперь, конечно, вы можете спорить, что именно это означает, но что бы вы ни решили, решение влияет на ответ на вопрос. Ни один из этих других вопросов не требует безопасной ГСЧ, и ни один из них не может дать достойный ответ, как масштабировать значение в диапазоне 1-100. Steve Jessop
Я на Windows Vista. akway
На какой платформе вы работаете. Существует базовая функция rand (), но у каждой ОС есть лучшие способы генерации случайных чисел. Если вы укажете платформу, это будет проще для всех. i_am_jorf
В этот момент кто-то всегда говорит «определить высокое качество», так что это может быть и я. anon
Перейти к Radio Shack. Купить диод, резистор NTR, конденсатор и последовательный кабель. Отрежьте конец последовательного кабеля, который не подходит к вашему компьютеру. Припой диод и резистор последовательно между выводами DTR и DSR кабеля. Припой конденсатор между выводами DSR и TXD. Напишите небольшую программу на C, которая сделает следующее: Установите DTR на 1. Запустите таймер. Контролируйте DSR, пока не дойдет до 1. Остановите таймер. Рассчитать сопротивление по истекшему времени. Получить несколько битов из этого значения для использования в качестве части случайного числа. Повторяйте, пока не накопится достаточно битов. Теперь вы могли бы сдуть и (модуль) 100 ... user113476

Ваш Ответ

8   ответов
3

main()
{
  srand(time(0));

  for(int i=0;i<1000;++i)
    printf("%f ", ((float)rand())/RAND_MAX*99+1);

  return 0;
}

Это такое же равномерное распределение, какое может дать стандартный rand ().

Извините, это мера предосторожности, когда вы используете модуль. Это не так просто при выполнении масштабирования.
Как я уже сказал, он настолько случайный, насколько может быть rand (). Существуют и другие номера (например, твистер Мерсенна), которые имеют лучшую «случайность». И уверены ли вы в том, что дажеslightly более высокая вероятность имеет значение? Я делю все это до интервала [0,1] и умножаю обратно до [1100].
Масштабирование до числа с плавающей запятой или удваивает вводит в игру причуды представления с плавающей запятой. Вы можете получить странные псевдонимы по краям "мусорных ведер" & quot; когда вы увеличиваете масштаб.
Я ни в чем не уверен ;-) Но в комментарии ОП говорится, что он должен быть неотличим от случайных до 100 миллионов выборок. Если это так, значит, имеет значение смещение 0,3%. rand () может вернуть 32768 различных значений, и мы хотим отобразить их на 100 выходных данных. Поэтому независимо от того, что является источником случайности, 68 выходных сигналов будут на 0,3% более распространенными, чем остальные 32, если вы не примете стандартную меру предосторожности «перекатывания». в результате от(RAND_MAX - RAND_MAX % 100) вRAND_MAX включительно.
Я не думаю, что это "кажется случайным до 100 миллионов прогонов". Например, в Windows значение RAND_MAX равно 32767. Таким образом, если этот код исправлен, чтобы иногда не выводить 101, значения 2, 3, 5, 6 ... примерно на 0,3% чаще, чем значения 1, 4, 7 .. Я думаю, что в 100М выборках это смещение должно быть довольно очевидным, и это даже при условии, что rand () неотличима от случайной в очень многих выборках. Это почти наверняка не так, хотя я не могу произвести отличительный тест с манжеты.
2

Как высококачественный генератор случайных чисел,please не использоватьrand()или не код гарантированного качества. Очень легко сгенерировать случайное число неверно (см. Забавную историю Кнута в «Искусстве компьютерного программирования: Полу численные алгоритмы»). Самый простой способ продолжить это, возможно, использоватьгенераторы в научной библиотеке GNU, Он устанавливается одним щелчком мыши на * nux, и есть несколько портов GSL для Windows. Я использовал это. Это легко позвонить и работает хорошо.

1

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

Вы хотите фактический физический процесс. Смотрите Random.org. Вы готовы платить?

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

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


Каковы ваши требования? Будут ли сертифицированы ваши номера? Или ты простоwant действительно хорошие случайные числа? Какие тесты вы будете использовать, чтобы определить, является ли ваш генератор случайных сигналов «хорошим»?

Вы просмотрели инструменты, перечисленные в Википедии?en.wikipedia.org/wiki/Randomness_tests
Существуют метрики для измерения этих вещей, но они понимают, что люди плохо знают распознавание случайности, поэтому, когда вы говорите "появляются", " ты имеешь в виду, что тебя больше волнует появление случайности, а не случайность? Другими словами, истинные случайные числа являются «более странными» чем люди ожидают. Можете ли вы жить с истинной полосатостью или вы бы предпочли, чтобы она выглядела как "смотри" случайно для наблюдателя?
На макроуровне я хочу равномерного распределения, каждый номер идет примерно в 1% случаев. Но на микроуровне мне нужна высокая волатильность, когда любая часть из 100+ миллионов случайных чисел выглядит совершенно случайной. akway
7

Под «справедливым распределением» я предполагаю, что вы имеете в виду, что вы, как правило, не удовлетвореныrand(), В этом случае вам, вероятно, следует использовать специфичные для ОС методы, которые создают криптографически безопасные случайные числа -/dev/random или же/dev/urandom (в зависимости от ваших потребностей) на Unix иCryptGenRandom или жеRtlGetRandom на Win32. В частности, на Win32, если вы используете VS2005 или новее, вы можете просто использоватьrand_s.

Да, но, по крайней мере, если бы ты написал это сам, ты бы точно знал, что он облажался. :-)
+1 за использование известных библиотек, созданных кем-то другим. Нет лучшего способа использовать что-либо криптографически защищенное.
Согласитесь с необходимостью создания великолепной библиотеки, написанной людьми, которые проводят много времени, думая о проблеме и тестируя ее. Но меня всегда интересует, можно ли свести на нет выигрыш от использования одного из них, назвав его ненадлежащим.
Я полагаю, что весьма вероятно, что, если вы неправильно назвали библиотеку, вы, по крайней мере, с такой же вероятностью неправильно осуществите ее самостоятельно, если не больше.
3

http://mathworld.wolfram.com/RandomNumber.html

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

Это очень важно, если вы надеетесь создать что-то, что не может быть переработано, например, для покерных сайтов.

Бытьvery Осторожно, когда вы катите свой собственный ГСЧ, очень легко ошибиться, и очень трудно показать, что это неправильно.
Именно то, что мне было нужно. Спасибо. akway
Существует так много хороших, хорошо отлаженных PRNG, что использовать их бессмысленно. Это для обучения.
Да,DO NOT DO THIS, Люди, которые намного лучше, чем вы или я, сделали это.stackoverflow.com/questions/1046714/…
1

Другие посты имеют хороший совет. Если вы действительно хотите погрузиться в процесс генерации случайных чисел, взгляните наЧисленные Рецепты в Си, Начать сГлава 7.

8

Это самый простой способ получения равномерно распределенных случайных чисел в C:

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

#include <stdlib.h>

Step 2. Посеять генератор случайных чисел, используяsrand(), Семя определяет, где начинаются случайные числа. Последовательность случайных чисел всегда будет одинаковой для данного семени. Это позволяет получить случайные, но воспроизводимые результаты. Если вам не нужно, чтобы он был воспроизводимым, полезно посеять текущее время, так что случайная последовательность будет отличаться при каждом запуске.

srand(time(NULL));

(не забудьте указать time.h, если вы делаете это). Также,only seed the generator once per program run если вы не генерируете огромное количество (миллионов или миллиардов) случайных чисел. Посев часто делает последовательностьless случайным образом.

Step 3. Получите ваш случайный номер.

rand()

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

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

int random_number = rand() % range + min;

Где range - это количество (последовательных) чисел, из которых вы хотите выбрать, а min - наименьшее из них. Таким образом, чтобы сгенерировать число от 1 до 100, диапазон равен 100, а min равен 1:

int random_number = rand() % 100 + 1;

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

-1: использование% с рандом очень плохо. Создайте 10000 случайных чисел в [1, 100], и вы увидите довольно явное смещение. (Рассмотрим случай, когда RAND_MAX = 100, где вероятность того, что вы бросите 1, в два раза выше, чем у любого другого числа.)
Это плохой способ сделать это, так как если предпочитает числа в нижней части шкалы. Если RAND_MAX - что-то20, то все числа от 0 до 20 имеют повышенный шанс выбора. Это небольшое преимущество, поскольку RAND_MAX очень большое число, но тем не менее существует.
:: shrugs :: Для приложения, где «rand ()»; допустимо, смещение от модуля тривиально. При необходимости вы всегда можете написать обертку, чтобы обрезать оскорбительные броски и повторить попытку.
2

Стандартная библиотека C имеетрант этого, вероятно, будет достаточно, если у вас нет необходимости в prng с определенным статистическим распределением.

Похожие вопросы