2 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Генератор случайных чисел. Случайность, совпадение, закономерность. Генератор случайных чисел 1с 8 случайное число

Случайность, совпадение, закономерность. Генератор случайных чисел




В продолжение моей темы: 1С:Альфа-Авто Автосалон Автосервис: обмен с сайтом.
С помощью данного скрипта можно загружать в автоматическом режиме, по расписанию, данные сервисных книжек (ремонтов авто) из 1С:Альфа-Авто Автосалон Автосервис.
Также можно загружать данные в ручном режиме: для этого делается скрытая страница, где размещается специальная кнопка.
Комментарии размещенные внутри скрипта разъяснят логику и порядок действия.
Комментарии с «///// echo» использовались для отладки.
Дополнительно создана таблица для журналирования результатов загрузки данных.
Скрипт включает в себя защиту от SQL инъекций (думаю безопасность соблюдена в полной мере).
В кратце:
1. Пишется скрипт, который запускает этот.
2. Создается регламентное задание в WordPress, по которому запускается скрипт из п.1.
3. Этот скрипт осуществляет проверку на существование файла обмена в папке.
4. Если данные не новые, загрузка не производится.
5. Если данные новые, очищается таблица сервисных книжек.
6. Загружаются новые данные.

Собственно сам скрипт:

Причем то, что получается в случае Реквизит1 — очень бесит, когда генератор находится в отдельной функции — такая ситуация постоянна.

Воспроизводится с древних релизов 8.2 по последний релиз 8.3

Приходится генератор помещать как результат выполнения функции в модуль повторного использованияповторного использования на вызов.

Объясню как наткнулся, есть связь элементов один ко многим, Ввели некую аналитику и на момент запуска надо было имеющие данные псевдо-случайно более равномерно раскидать, я без задней мысли написал функцию выдачи случайного числа, и обработал связи, сказать что я был удивлен результату — ничего не сказать, а самое обидное что при обходе кода отладкой — не воспроизводится эта ситуация, без нее — воспроизводится.

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

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

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

Например, сгенерировали 10000 чисел, но выбрать из них только 1000.

Можно придумать еще много способов.

Есть просто случайные числа. А есть «хорошие» случайные числа. Их используют, например, для случайного воспроизведения песен

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

(7) Хорошесть там не в том чтобы все. ктож все 100 тыщ своих песен слушает за раз?

(3) вы просто не правильно им пользуетесь… генератор надо создать один раз и потом получить от него последовательность… не правильно создавать генератор для получения одного числа…

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

(10) да я только хотел сказать, что это не коллизия, а нормальное поведение генератора… даже в .Net то же самое…

интересно, каким открытием для автора будет наличие криптографически стойких генераторов ПСЕВДО случайных чисел…

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

(13) для озвученной задачи подойдет кодирование, либо сопоставление номера некоему генерируемому токену, который также уникален

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

(12)Никаким, я про это знаю 🙂

(15) и зачем такие сложности?

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

я кстати однажды делал случайные числа 1с-ом следующим образом, когда не мог использовать ВК (а ВК такая у меня есть) я заранее сгенерировал не 1С массив чисел и потом обычным 1С генератором использовал значения массива в качестве сида (опорных значений), повторений не было, хотя понятно что честным ГПСЧ это назвать сложно

(17)Токен тоже сложность. Программирование вообще непросто.

(20) ок, я так завуалировал бредовый способ идентификации, ок?

(20) про сложность программирования, это наверное прикол, в контексте вашей статьи

(21)Могли не вуалировать, бред в комментариях у вас хорошо получается

(25) мои комментарии не обязательны к прочтению, у вас была возможность пройти мимо и не писать херни…понять, что, то что вы вместо идентификаторов используете хреновый алгоритм генерации случайных чисел, якобы из-за того, что кто может додуматься прибавить 1 (а случайные числа видимо генерируют такие числа, которые не являются соседними для уже сгенерированных ранее когда либо sic!) программированию вас бесполезно учить

(25) ты на скрин блин посмотри свой — 715, 715, 716. ок, убираем твои идиотским алгоритмом повторы. внимание вопрос на миллион, 715 и 716 это соседние в твоей терминологии числа или нет?

(26)Читаем тему, исследуется объект 1С и его качества, а ваши комментарии не в тему, бред и выпендреж.

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

(29) ну и что дает разброс в контексте вышеописанного случая? в чем проблема клиенту перебрать числа от 1 до 1000 и получить нужное? пример про клиента бред, а не мои комментарии

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

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

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

(32) млять причем здесь генераторслучайныхчисел. ты написал, цитирую:

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

(33)Вывод понятен из текста и только дебил это не понимает и несет бред.

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

Читать еще:  Что такое уздг при беременности. как делают уздг при беременности. нормы и расшифровка уздг при беременности

(34) еше раз, как твоя уникальность или не уникальность или что еще, спасет от того , что скрипт переберет диапазон чисел от 1 до миллиарда? ну скажи честно, что ты прикидывешься особенным

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

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

(37) как спасет увеличение интервала от брутфорса? КАК? для машины перебрать все int32 и даже long проще простого за приемлимое время, программыст. какая нахрен секретность

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

(38)Кто даст перебирать все номера, сайт ограничивает скорость ввода, например 1 в секунду и тогда придется подбирать долго.

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

«Генератор случайный чисел выдает одинаковые значения, да еще последовательно.» Собственно — это один из тестов, который показывает, что человеческий мозг — плохой генератор случайных чисел. Тест в следующем: выдайте ряд случайных чисел со значениями от 1 до 6, как правило человек, помимо прочего выдает именно НЕ повторяющиеся значения, что не является правильным.

Хотите уникальный номер, есть ведь GUID — генерируйте на здоровье, зачем велосипед изобретать?

(31)В комменте (20) больная самооценка нашла выпендреж.

Вы предложили, то что к статье не относится, полный оффтоп.

Давайте предлагать клиентам код в виде 93247skdYUkslkcn838792, для проверки статуса рекламации. Я думаю он просто позвонит по телефону и спросит: «Ну, как там мое оборудование, уже отремонтировали?»

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

(43) а давайте будем предлагать числа с большим интервалом, ага . 14153639478675186324759348759384756398 подойдет, да?

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

(41)Во первых можно применять последовательность из 20 цифр, а не int32.

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

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

Числа удобнее тем, то не возникает разночтений между «С» и «C».

По комбинаторике, если мы увеличиваем количество возможных символов, то увеличиваем основание для вариантов, а если увеличиваем разрядность то увеличиваем степень. Например:

Буквы английского алфавита и цифры, в основании получаем 36 и разрядов предполагаем 10 (36#k8SjZc9Dxk10 = 3,6561584 × 10#k8SjZc9Dxk15), или только числа, в основании и 20 разрядов (10#k8SjZc9Dxk20). Второй вариант дает большее число.

(45)По крайней мере нет разночтений в буквах.

Генератор случайных чисел!

Для просмотра формул ваш браузер должен поддерживать MathML.

Интересует взаимосвязь генератора случайных чисел и теории вероятностей. Что можно сказать по этому поводу?
В моем понятии генератор случайных чисел — это что-то, что построено только потому, что существует сама теория вероятностей. ГСЧ является применением ТВ на практике. Т.е. в принципе ГСЧ подчиняется законам ТВ, а соответственно в какой-то степени можно предсказывать тот или иной результат.

С другой стороны ГСЧ — просто ни к чему не привязанный алгоритм, который работает сам по себе, не опираясь на исход предыдущих опытов

Представим, что имеется шанс выпадения орла равный 10%. С ГСЧ было проведено 9 опытов и выпадала решка. С одной стороны алгоритму без разницы на исход следующего опыта. С другой стороны вроде бы следующим должен(не знаю, уместно ли слово «должен») упасть орел. Можно ли утверждать, что с большой долей вероятности выпадет орел или же все просто как палка и шанс выпадения орла останется 10%? Скорее всего, что все просто как палка и шанс орла на 10м опыте останется 10%. Но, если я возьму 100 абсолютно одинаковых ГСЧ, на каждом из них соберу по 9 опытов подряд с результатом «решка» и начну спорить с кем-либо, что последующий 10ый опыт на каждом из 100 ГСЧ даст более чем 10 «орлов» в итоге, окажусь ли я правым или проиграю спор?

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

ГСЧ при неизменности исходных данных и запуске с исходной позиции будет вырабатывать одну и ту же последовательность. Стандартизованные ХЭШ- и ЭЦП-функции (есть стандарт РФ) — это классы ГСЧ. Новая случ. последовательность формируется, если изменились начальные условия. Для ХЭШ — это обрабатываемый текст. Для ЭЦП — текст, закрытый ключ и др. данные.

Эх если бы все так легко было все бы давно были милионерами играя на Форексе или казино, но все-таки определенные законы хаоса есть, хотя получается это уже не хаос.
Кто хоть что-то понимает в этом может посмотреть одну системку, мне лично она помогает(+интуиция):
http://www.modber.ru/catalog/item2061.html

Редактировалось 1 раз(а). Последний 23.07.2013 10:50.

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

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

Форекс и казино- это не хаос,это другое.

Есть три известных:
1- порядковый номер генерации
2- хэш генерации
3- сгенерированое число

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

играл в jellyfish backgammon windows 98 se в 2000-2003 году, в конце уже в матче из 3-9 партий набирал больше чем самый сильный уровень программы, тупо интуицией «взломал» гсч машинки 🙂 человек сильнее любой машины, нужно только желание и ресурсы. с тех пор играю только в игры с полной информацией с машиной и то неохотно. всегда можно или посмотреть исходник или дизассемиблировать программу и «положить на лопатки»

Читать еще:  Выплаты многодетным к 1 сентября. Какие выплаты положены первокласснику малоимущим и многодетным семьям

Редактировалось 1 раз(а). Последний 19.06.2019 10:54.

Есть три известных числа:
Первое число 257
Второе число 0587938
Третье число 26
Каждый раз они меняются:
258
87
1974987

185
96
1562592
Как исходя из этих данных вычислить алгоритм генерации второго числа?
И каков будет алгоритм?

если алгоритм гсч «посолен», (например, два каких-то знака температуры камня и(или) последние байты занятого объема оперативки и(или) время в микросекундах от запуска скажем, алгоритма с солью в момент расчета, или еще Бог знает что можно напридумывать), — то нельзя НИКАК.

Редактировалось 1 раз(а). Последний 19.06.2019 20:59.

Цитата
phenix
Есть три известных числа:
Первое число 257
Второе число 0587938
Третье число 26
Каждый раз они меняются:
258
87
1974987

185
96
1562592
Как исходя из этих данных вычислить алгоритм генерации второго числа?
И каков будет алгоритм?

например в рулетке из 37 чисел идет генерация по сумме своих чисел поэтому там встречаются часто комбинации 13-31 6-15 23-32 2-29 12-21 или все 9 видов по 4 числа или добавлением 0 ..10-20-30 что добавляет 10 вид за счет которого система идет в + то же самое в покере туз играет как 1 и как высшая карта 14 поэтому если понаблюдать (я 16 лет постоянно играю в покер от 10 столов до 20 ) то частота выпадения туза выше других видов карт —так как генератор туза видит 8 тузов а не 4 и кроме этого генерация по сумме своих чисел 1-14-5 2-валет (11) 3-дама(12) 4-корль(13) 6-7-8-9 без пар 10-1(туз)-5-14(туз) —но это начало как в рулетке так и в картах потом идет генерация 3-6-9 11 . 5.. простых значении тем более в 36 чисел у нас 12 кратных 3 . четных и нечетных простых не кратных 3 почти одинаковое количество кроме 1..25 и 35 но к простым добавляется четное 2 и 3 выходит одинаковое количество четных и простых не кратных 3 но включая 3 как простое . и если играть например четное нечетное то лучше всегда играть четное не кратное 3 и простые числа вместо нечетных .при честной игре нет разницы что живой дилер что электро. в покере при 9 участниках если ва-банк пойдут 4 игрока и из них у трех есть туз то на столь 80% падает 4 туз. то же самое в рулетке больше всего шанс выпадания последующего числа по сумме своих чисел больше чем другого вида чисел.

даже в вашем примере 258=87=96=6 или 257=185=5 шанс выпадения после 258 например 87 или 96 больше

Редактировалось 6 раз(а). Последний 25.06.2019 00:49.

Урок №71. Генерация случайных чисел

Обновл. 30 Дек 2019 |

Возможность генерировать случайные числа очень полезна в некоторых видах программ, в частности в играх, программах научного или статистического моделирования. Возьмём, к примеру, игры без рандомных (или ещё «случайных») событий — монстры всегда будут атаковать вас одинаково, вы всегда будете находить одни и те же предметы/артефакты, макеты темниц и подземелий никогда не будут меняться и т.д., в общем, сюжет такой игры не очень и вряд ли вы долго продержитесь.

Генератор псевдослучайных чисел

Так как же генерировать случайные числа? В реальной жизни мы часто бросаем монетку (орёл/решка), кости или перетасовываем карты. Эти события включают в себя так много физических переменных (например, сила тяжести, трение, сопротивление воздуха и т.д.), что они становятся почти невозможными для прогнозирования/контроля и выдают результаты, которые во всех смыслах являются случайными.

Однако компьютеры не предназначены для использования физических переменных — они не могут бросить монетку, кости или перетасовать реальные карты. Компьютеры живут в контролируемом электрическом мире, где есть только два значения (true и false), чего-то среднего между ними нет. По своей природе компьютеры предназначены для получения прогнозируемых результатов. Когда мы говорим компьютеру посчитать, сколько будет 2 + 2 , мы всегда хотим, чтобы ответом было 4 (не 3 и не 5 ).

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

Генератор псевдослучайных чисел (или ещё «ГПСЧ») — это программа, которая принимает стартовое/начальное значение и выполняет с ним определённые математические операции, чтобы конвертировать его в другое число, которое совсем не связанное со стартовым. Затем программа использует новое сгенерированное значение и выполняет с ним те же математические операции, что и с начальным числом, чтобы конвертировать его в ещё в одно новое число — третье, которое не связано ни с первым, ни со вторым. Применяя этот алгоритм к последнему сгенерированному значению, программа может генерировать целый ряд новых чисел, которые будут казаться случайными (при условии, что алгоритм будет достаточно сложным).

На самом деле, написать простой ГПСЧ не так уж и сложно. Вот небольшая программа, которая генерирует 100 рандомных чисел:

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

Функции srand() и rand()

Языки C и C++ имеют свои собственные встроенные генераторы случайных чисел. Они реализован в двух отдельных функциях, которые находятся в заголовочном файле cstdlib:

Функция srand() устанавливает передаваемое пользователем значение в качестве стартового. srand() следует вызывать только один раз: в начале программы (обычно в верхней части функции main()).

Функция rand() генерирует следующее случайное число в последовательности. Оно будет находиться в диапазоне от 0 до RAND_MAX (константа в cstdlib, значением которой является 32 767).

Вот пример программы, использующей эти две функции:

Стартовое число и последовательности в ГПСЧ

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

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

Помните, что каждое новое число в последовательности ГПСЧ генерируется исходя из предыдущего определённым способом. Таким образом, при любом начальном числе ГПСЧ всегда будет генерировать одну и ту ​​же последовательность! В программе выше последовательность чисел всегда одинакова, так как стартовое число всегда равно 4 541.

Читать еще:  Лиру свадебное поздравление оригинальное. Самые прикольные поздравления на свадьбу с вручением денег

Чтобы это исправить нам нужен способ выбрать стартовое число, которое не будет фиксированным значением. Первое, что приходит на ум — использовать рандомное число! Это хорошая мысль, но если нам нужно случайное число для генерации случайных чисел, то это какой-то замкнутый круг, вам не кажется? Оказывается, нам не обязательно использовать случайное стартовое число — нам просто нужно выбрать что-то, что будет меняться каждый раз при новом запуске программы. Затем мы сможем использовать наш ГПСЧ для генерации уникальной последовательности рандомных чисел исходя из уникального стартового числа.

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

В языке C есть функция time(), которая возвращает в качестве времени общее количество секунд от полуночи 1 января 1970 года. Чтобы использовать эту функцию, нам просто нужно подключить заголовочный файл ctime, а затем инициализировать функцию srand() вызовом функции time(0).

Вот та же программа, что выше, но уже с использованием функции time() в качестве стартового числа:

Чтобы сымитировать бросок кубика — вызываем функцию getRandomNumber(1, 6) .

Какой ГПСЧ является хорошим?

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

Хороший ГПСЧ должен иметь ряд свойств:

Свойство №1: ГПСЧ должен генерировать каждое новое число с примерно одинаковой вероятностью. Это называется равномерностью распределения. Если некоторые числа генерируются чаще, чем другие, то результат программы, использующей ГПСЧ, будет предсказуем!

Например, предположим, вы пытаетесь написать генератор случайных предметов для игры. Вы выбираете случайное число от 1 до 10, и, если результатом будет 10, игрок получит крутой предмет вместо среднего. Шансы будут 1 к 10. Но, если ваш ГПСЧ не равномерно генерирует числа, например, 10-тки генерируются чаще, чем должны, то ваши игроки будут получать более редкие предметы чаще, чем предполагалось, и сложность + интерес к такой игре автоматически уменьшается.

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

Свойство №2: Метод, с помощью которого генерируется следующее число в последовательности, не должен быть очевиден или предсказуем. Например, рассмотрим следующий алгоритм ГПСЧ: num = num + 1 . У него есть равномерность распределения рандомных чисел, но это не спасает его от примитивности и предсказуемости!

Свойство №3: ГПСЧ должен иметь хорошее диапазонное распределение чисел. Это означает, что маленькие, средние и большие числа должны возвращаться случайным образом. ГПСЧ, который возвращает все маленькие числа, а затем все большие — предсказуем и приведёт к предсказуемым результатам.

Свойство №4: Все ГПСЧ являются циклическими, т.е. в какой-то момент последовательность генерируемых чисел начнёт повторяться. Как упоминалось ранее, ГПСЧ являются детерминированными, и с одним значением ввода мы получим одно и то же значение вывода. Подумайте, что произойдёт, когда ГПСЧ сгенерирует число, которое уже ранее было сгенерировано. С этого момента начнётся дублирование последовательности чисел между первым и последующим появлением этого числа. Длина этой последовательности называется периодом.

Например, вот представлены первые 100 чисел, сгенерированные ГПСЧ с плохой периодичностью:

112 9 130 97 64
31 152 119 86 53
20 141 108 75 42
9 130 97 64 31
152 119 86 53 20
141 108 75 42 9
130 97 64 31 152
119 86 53 20 141
108 75 42 9 130
97 64 31 152 119
86 53 20 141 108
75 42 9 130 97
64 31 152 119 86
53 20 141 108 75
42 9 130 97 64
31 152 119 86 53
20 141 108 75 42
9 130 97 64 31
152 119 86 53 20
141 108 75 42 9

Заметили, что он сгенерировал 9 как второе число, а затем как 16-е. ГПСЧ застревает, генерируя последовательность между этими двумя 9-ми: 9-130-97-64-31-152-119-86-53-20-141-108-75-42- (повтор).

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

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

Почему rand() является посредственным ГПСЧ?

Алгоритм, используемый для реализации rand(), может варьироваться в разных компиляторах, и, соответственно, результаты также могут быть разными. В большинстве реализаций rand() используется Линейный Конгруэнтный Метод (или ещё «ЛКМ»). Если вы посмотрите на первый пример в этом уроке, то заметите, что там, на самом деле, используется ЛКМ, хоть и с намеренно подобранными плохими константами.

Одним из основных недостатков функции rand() является то, что RAND_MAX обычно устанавливается как 32 767 (15-битное значение). Это означает, что если вы захотите сгенерировать числа в более широком диапазоне (например, 32-битные целые числа), то функция rand() не подойдёт. Кроме того, она не подойдёт, если вы захотите сгенерировать случайные числа типа с плавающей запятой (например, между 0.0 и 1.0), что часто используется в статистическом моделировании. Наконец, функция rand() имеет относительно короткий период по сравнению с другими алгоритмами.

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

Для приложений, где требуется высококлассный ГПСЧ, рекомендуется использовать алгоритм Вихрь Мерсенна (англ. «Mersenne Twister»), который генерирует отличные результаты и относительно прост в использовании.

Отладка программ, использующих случайные числа

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

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

Рандомные числа в C++11

В C++11 добавили тонну нового функционала для генерации случайных чисел, включая алгоритм Вихрь Мерсенна, а также разные виды генераторов случайных чисел (например: равномерные, генератор Poisson и т.д.). Доступ к ним осуществляется через подключение заголовочного файла random. Вот пример генерации случайных чисел в C++11 с использованием Вихря Мерсенна:

Источники:

http://open-budget.ru/public/730095/
http://www.mathforum.ru/forum/read/1/40024/
http://ravesli.com/urok-71-generatsiya-sluchajnyh-chisel-funktsii-srand-i-rand/

Ссылка на основную публикацию
Статьи c упоминанием слов:
Adblock
detector