Cc++ — Random в Си


Содержание

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

Функция, генерирующая псевдослучайные числа, имеет прототип в файле библиотеки stdlib.h :

Если необходимо сгенерировать последовательность в диапазоне [M1; M2], то используется формула:

Number = rand()%(M2-M1+1) + M1;

где Number – генерируемое число. M2-M1+1 – полный диапазон представления чисел. M1 – смещение указанного диапазона относительно 0; % — остаток от деления.

Например, если требуется сгенерировать последовательность в диапазоне [-10;10], то вызов функции будет выглядеть как

В результате получения остатка от деления на 21 имеем число от 0 до 20. Вычитая из полученного числа 10, получим число в искомом диапазоне [-10;10].

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

Для генерации различных последовательности при каждом запуске программы необходимо проинициализировать глобальную переменную next значением, отличным от 1. С этой целью используется функция
void srand( unsigned int seed)
< next = seed; >
Чтобы инициализация next при каждом запуске программы была различной в качестве аргумента seed чаще всего используется текущее время.

Пример Заполнить массив из 20 элементов случайными числами в диапазоне от 0 до 99.

Алгоритм перемешивания

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

Реализация на Си

Алгоритм произвольного выбора

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

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

Реализации на Си
В результате получаем новый массив b , сформированный произвольной выборкой элементов массива a .

#include
#include
#include
#define SIZE 20
int main() <
int a[SIZE];
int b[SIZE]; // результирующий массив
srand(time( NULL ));
// Заполняем массив последовательными значениями от 1 до 20
for ( int i = 0; i «%2d » , a[i]);
>

for ( int i = 0; i int ind = rand() % 20; // выбираем произвольный индекс
while (a[ind] == -1) // пока элемент «выбран»
<
ind++; // двигаемся вправо
ind %= 20; // если дошли до правой границы, возвращаемся в начало
>
b[i] = a[ind]; // записываем следующий элемент массива b
a[ind] = -1; // отмечаем элемент массива a как «выбранный»
>
printf( «\n» );
// Выводим получившийся массив
for ( int i = 0; i «%2d » , b[i]);
getchar();
return 0;
>

Как генерировать случайные числа в диапазоне?

Я изучаю массивы и не могу понять, что я делаю неправильно.

Мне нужно вывести массив с 8 случайных чисел от 5 до 25.

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

Где проблема в моем коде, и почему мое случайное число не генерирует новое число, пока я зацикливаюсь по массиву?

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

Есть ли кто-нибудь, кто может объяснить, что я сделал неправильно, и почему мой цикл не работает правильно?

Решение

В с ++ 11, с random Услуги, которые вы можете сделать

Другие решения

Генерация случайных чисел в диапазоне в C ++ не так тривиальна, как я знаю. В моем примере вам нужно иметь функции srand () и rand ().


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

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

Эта строка вычисляет значение, выполняя выражение rand() % 25 + 5 и помещает это значение в переменную random_number , Например, может быть, он вычисляет значение 20 помещает это значение в переменную. Всякий раз, когда вы извлекаете значение из переменной, вы получите последнее введенное число.

Эта строка принимает переменную random_number и извлекает его значение (скажем, 20 ) и назначает его table[i] , Важным моментом является то, что здесь не имеет значения, как random_number получил свое значение. Вы кладете значение в поле, и вы только получите это значение обратно.

Если вы хотите, чтобы значение переменной изменилось, вы должны изменить его:

Если вам нужен объект, который выполняет код при оценке, тогда вам нужна функция:

После определения этой функции вы можете использовать random_number() переоценить выражение:

Обратите внимание на разницу здесь: random_number() это вызов функции, который повторяет rand() % 25 + 5 выражение, а не переменная. Переменные — это просто хранилище для любых данных, которые вы в последний раз вводили. Функции запускают код при их вызове.

Предположим, вы хотите сгенерировать случайные числа в диапазоне [начало, конец]:

дает случайное целое число в [0, конец).

Итак, сначала вы генерируете случайное число в [0, (end-start)], а затем добавляете «start» в этот диапазон, чтобы получить желаемый диапазон, как показано ниже.

[0 + начало, конец-начало + начало] = [начало, конец]

Генерация случайного числа в диапазоне на С++

В этой теме 0 ответов, 1 участник, последнее обновление Васильев Владимир Сергеевич 8 мес., 2 нед. назад.

Чтобы получить случайное число в С++ используется функция rand() из модуля . Она генерирует псевдослучайные целые числа в диапазоне от нуля до константы RAND_MAX , значение которой зависит от компилятора (стандартом языка не регламентируется).

Цукерберг рекомендует:  Код - Нужно написать код

Числа псевдослучайные, значит используется некий алгоритм генерации, это может бычть что угодно, например линейный конгруэнтный датчик — стандарт также не фиксирует этот вопрос. Важно, что все такие алгоритмы используют «затравку», то есть некоторое первое число, с которого начинается генерация. Если мы не зададим это число — то будет использоваться скорее всего ноль, а при каждом запуске программы мы будем получать одинаковые случайные числа. Задавать эту константу заранее известным значением удобно, например, для тестирования программы. Однако, если мы хотим чтобы значения были каждый раз новые — нужно использоваться функцию srand(int) , которая задает значение затравки.

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

Чтобы сгенерировать число в диапазоне от 0 до to , можно использовать деление по модулю:

Генерация в диапазоне от from до to — это тоже самое, что генерация от нуля до to-from , но к результату надо добавить to:

При этом, необходимо, чтобы from был меньше to .

Про функции rand, srand и одинаковые случайные числа

Немного исследуем функцию rand, для этого напишем такой пример:

Сколько бы мы ее не запускали — будем получать одинаковый результат. Но почему? Давайте разбираться вместе. Загляним внутрь одной из возможных реализаций этой функции:

Функция возвращает целые числа (от 0 до 32767). Не вдаваясь в подробности этого кода, полученное случайное число, зависит от стартового числа next , которое, как вы видите, установлено в единицу. Отсюда и следует, что числа всегда получаются одинаковыми. Для того, чтобы избежать этой проблемы, в паре с rand() нужно использовать функцию srand( ). Вот ее внутренности:

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

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

Передадим в функцию srand() текущее системное время:

Массив случайных чисел

Часто нужно сгенерировать массив случайных чисел некоторого типа. Причём имеется верхняя и нижняя граница элементов этого массива.

Проще всего решить такую задачу генерируя случайные числа в цикле for.

Для примера рассмотрим генерацию двух случайных массивов — вещественного и целочисленного. В каждом из них будет 10 элементов. И элементы каждого из массивов будут от 1 до 5. Все эти константы Вы можете поменять на какие-нибудь свои. Для удобства оформим генерацию каждого из массивов с помощью отдельной функции:


Генератор вещественных чисел C++

Пытаюсь выполнить задание:

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

Никак не могу сгенерировать значения — получаются либо меньше единицы, либо больше. Дошло до того, что начал делать «примитивно», как в коде ниже, без подобных конструкций:
(double)(rand()) / RAND_MAX * (max — min) + min
Проблема в том, что массив заполняется теперь 0 или 1, не знаю, что делать с заданием. Прошу вашей помощи.
Код ниже:

C/c++ — Random в Си

В статье вы узнаете, как использовать std.random и чем он хорош

Содержание

В 2011 году новый стандарт C++11 добавил в язык заголовок , в котором описаны средства для работы со случайными числами на профессиональном уровне. Эти средства заменяют функцию rand и дают гораздо больше гибкости.

Но чтобы этим воспользоваться, надо немного разбираться в теории.

Почему в IT все числа неслучайные

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

  • Для генерации по-настоящему случайных, ничем не связанных чисел операционной системе приходится использовать средства, недоступные обычным приложениям; такие случайные числа называются криптографически стойкими случайными числами
  • Генерация системой таких случайных чисел работает медленно, и при нехватке скорости система просто отдаёт приложениями псевдослучайные числа либо заставляет их ожидать, пока появится возможность вернуть случайное число

Вы можете узнать об этом подробнее, прочитав о разнице между устройствами /dev/random и /dev/urandom в ОС Linux

Pseudo-random Numbers Generator (PRNG)

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

Общий принцип генерации легко показать в примере:

Несложная итеративная формула, содержащая умножение, сложение и деление по остатку на разные константы, создаёт целую серию чисел, похожих на случайные:

Очевидно, что между числами есть взаимосвязь: они вычислены по одной и той же формуле. Но для пользователя видимой взаимосвязи нет.

Время как источник случайности

Если вы запустите предыдущую программу несколько раз, вы обнаружите проблему: числа будут те же самые. Причина проста — в начале последовательности мы используем всегда одно и то же число, 18. Для последовательности это число является зерном (англ. seed), и чтобы последовательность менялась с каждым запуском, зерно должно быть случайным.

Простейший, но не самый лучший способ получения зерна: взять текущее календарное время в секундах. Для этой цели мы воспользуемся функцией std::time_t time(std::time_t* arg).

Функция std::time возвращает число, представляющее время, прошедшее с полуночи 1 января 1970 года. Обычно это время в секундах, также известное как UNIX Timestamp. Параметр arg можно игнорировать и передавать нулевой указатель (вы можете в этом убедиться, прочитав документацию).

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

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

Ограничение числа по диапазону

Ограничить числа по диапазону можно путём деления по остатку (что сократит длину входного диапазона) и добавления нижней границы диапазона:

Всё то же, только лучше: заголовок

Заголовок random разделяет генерацию псевдослучайных чисел на 3 части и предоставляет три инструмента:

  • класс std::random_device, который запрашивает у операционной системы почти случайное целое число; этот класс более удачные зёрна, чем если брать текущее время
  • класс std::mt19937 и другие классы псевдо-случайных генераторов, задача которых — размножить одно зерно в целую последовательность чисел
  • класс std::uniform_int_distribution и другие классы распределений


Класс mt19937 реализует алгоритм размножения псевдослучайных чисел, известный как Вихрь Мерсенна. Этот алгоритм работает быстро и даёт хорошие результаты — гораздо более “случайные”, чем наш самописный метод, показанный ранее.

О распределениях скажем подробнее:

  • линейное распределение вероятностей (uniform distribution) возникает, когда вероятность появления каждого из допустимых чисел одинакова, т.е. каждое число может появиться с равным шансом
  • в некоторых прикладных задачах нужны другие распределения, в которых одни числа появляются чаще других — например, часто используется нормальное распределение (normal distribution)
Цукерберг рекомендует:  Помощь - Вопрос по языку swift

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

Теперь мы можем переписать

Особенность платформы: random_device в MinGW

Согласно стандарту C++, принцип работы std::random_device отдаётся на откуп разработчикам компилятора и стандартной библиотеки. В компиляторе G++ и его стандартной библиотеке libstdc++ класс random_device правильно работает на UNIX-платформах, но на Windows в некоторых дистрибутивах MinGW вместо случайных зёрен он возвращает одну и ту же константу!

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

Приём №1: выбор случайного значения из предопределённого списка

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

Идея проиллюстрирована в коде

Приём №2: отбрасываем неподходящее значение

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

Тогда используйте цикл, чтобы запрашивать случайные значения до тех пор, пока очередное значение не попадёт под ваши требования. Будьте аккуратны: если требования нереалистичные, вы получите бесконечный цикл!

Доработаем программу, добавив цикл while в функцию main. Для сохранения уже использованных имён воспользуемся структурой данных std::set из заголовка , представляющей динамическое множество.

Генерация (псевдо)случайных чисел

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

На помощь нам приходит функция стандартной библиотеки языка Си (не C++) rand() .

Она генерирует псевдослучайное целое число на интервале значений от 0 до RAND_MAX . Последнее является константой, которая варьируется в зависимости от реализации языка, но в большинстве случаев составляет 32767.
А что если нам нужны случайные числа от 0 до 9? Типичный выход из ситуации — использование операции деления по модулю.

Если нам нужны числа от 1 (а не от 0) до 9, то можно прибавить единичку…

Идея такая: генерируем случайное число от 0 до 8, и после прибавления 1 оно превращается в случайное число от 1 до 9.

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

Исправить ситуацию помогает функция srand() .

void srand (unsigned int seed);

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

Но проблема осталась. Как сделать случайным зерно, ведь от него все зависит?
Типичный выходит из ситуации — использование функции time() .

time_t time (time_t* timer);

Она тоже досталась в наследство от языка Си и, будучи вызвана с нулевым указателем в качестве параметра, возвращает количество секунд, прошедших с 1 января 1970 года. Нет, это не шутка.

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

Для использования функций rand() и srand() нужно подключить заголовочный файл , а для использования time() — файл .

Функция Random C++


В разгар создания STL и бурной войны за стандарт языка C++ ряд программистов разработали собственную кроссплатформенную библиотеку классов, обеспечивающих разработчиков инструментами для решения повседневных задач, таких как обработка данных, алгоритмы, работа с файлами и т. д. Эта библиотека называется Boost. Проект настолько успешен, что возможности Boost заимствуются и вписываются в стандарт языка, начиная с C++11. Одним из таких дополнений является усовершенствованная работа со случайными числами.

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

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

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

Традиционный алгоритм создания СЧ совмещал в себе одновременно алгоритм создания непредсказуемых битов и превращение их в последовательность чисел. В библиотеке random C++, являющаяся частью Boost, разделили эти два механизма. Теперь генерация случайных чисел и создание из них распределения (последовательности) происходит отдельно. Использование распределения является совершенно логичным. Потому что случайное число без определенного контекста не имеет смысла и его сложно использовать. Напишем простую функцию, которая бросает кость:

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

Некоторые считают такое ее использование допустимым. Ведь C++ позволяет так работать. Однако создателями библиотеки Boost и стандартов C++11 строго рекомендуется так не делать. В лучшем случае это окажется просто плохой на вид код, а в худшем – это будет работающий код, совершающий ошибки, которые очень сложно поймать. Использование распределений гарантирует, что программист получит то, что ожидает.

Инициализация генератора и seed

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

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

«31255» — это называется seed (семя, первоисточник) — число, на основе которого генератор создает случайные числа. Ключевым моментом здесь является то, что при такой инициализации тип seed должен быть таким же или приводимым к типу, с которым работает генератор. Этот тип доступен через конструкцию decltype(e()), или result_of, или typename.

Почему генератор создает одинаковые последовательности?

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

Соответственно, чтобы избежать повторения последовательности чисел, генератор должен инициализироваться разными значениями при каждом запуске программы. Как раз для этих целей можно использовать seed. Стандартным способом инициализации ГПСЧ является передача ему в качестве seed значения time(0) из заголовочного файла ctime. То есть генератор будет инициализироваться значением, равным количеству секунд, прошедших с момента 1 января 00 часов 00 минут 00 секунд, 1970 года по UTC.

Цукерберг рекомендует:  Java - Коллекция Dictionary

Инициализация ГПСЧ другим генератором

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

Random_device – генератор истинно случайных чисел

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

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

Использование random_device в качестве seed для ГПСЧ

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

Стоит также отметить, что значение инициализации генератора может быть сброшено в любой момент:

Обобщим: генераторы и распределения

Генератор (engine) – это объект, который позволяет создавать разные равновероятные числа.

Распределение (distirbution) – это объект, который преобразует последовательность чисел, созданных генератором, в распределения по определенному закону, например:

  • равномерное (uniform);
  • нормальное — гауссово (normal);
  • биномиальное (binomial) и т. д.

Рассмотрим генераторы стандартной библиотеки C++.

  1. Новичкам достаточно использовать default_random_engine, оставив выбор генератора библиотеке. Выбран будет генератор на основе сочетания таких факторов, как производительность, размер, качество случайности.
  2. Для опытных пользователей библиотека предоставляет 9 заранее настроенных генераторов. Они сильно отличаются друг от друга производительностью и размерами, но в то же время их качество работы было подвержено серьезным тестам. Часто используется генератор под названием Mersenne twister engines и его экземпляры mt19937 (создание 32-битных чисел) и mt19937_64 (создание 64-битных чисел). Генератор представляет собой оптимальное сочетание скорости работы и степени случайности. Для большинства возникающих задач его будет достаточно.
  3. Для экспертов библиотека предоставляет собой конфигурируемые шаблоны генераторов, позволяющие создавать дополнительные виды генераторов.

Рассмотрим ключевые аспекты распределений. В стандарте языка их насчитывается 20 штук. В примере выше использовалось равномерное распределение библиотеки random C++ в диапазоне [a, b] для целых чисел — uniform_int_distribution. Такое же распределение можно использовать для действительных чисел: uniform_real_distribution с такими же параметрами a и b промежутка генерации чисел. При этом границы промежутка включены, то есть [a, b]. Перечислять все 20 распределений и повторять документацию C++ в статье смысла не имеет.


Следует отметить, что каждому распределению соответствует свой набор параметров. Для равномерного распределения это промежуток от a до b. А для геометрического (geometric_distribution) параметром является вероятность успеха p.

Большая часть распределений определена как шаблон класса, для которого параметром служит тип значений последовательности. Однако некоторые распределения создают последовательности только значения int или только значения real. Или, например, последовательность Бернулли (bernoulli_distribution) предоставляющая значения типа bool. Так же как и с ГСЧ, пользователь библиотеки может создавать собственные распределения и использовать с встроенными генераторами или с генераторами, которые создаст.

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

Краткая справка: Random в стиле .Net

В .Net framework также присутствует класс Random для создания псевдослучайных чисел. Рассмотрим пример генерации Random number С++/CLI.

Для тех, кто работает в Visual Studio и никак не может понять, почему пространство имен System не определено.

Чтобы работать с .net необходимо подключение CLR. Делается это двумя способами.1) Создание проекта не windows console app, а с поддержкой CLR — Console application CLR (Консольное приложение CLR).2) Подключить поддержку CLR в настройках уже созданного проекта: свойства проекта(вкладка «проект», а не «сервис») -> конфигурация -> общее -> значения по умолчанию -> в выпадающем списке пункта «поддержка общеязыковой среды выполнения(CLR)» выбрать «Поддержка CLR-среды (/clr)».

В данном случае вся работа происходит благодаря функции Random Next C++/CLI.

Стоит особо отметить, что .net является большой библиотекой с обширными возможностями и использует свою версию языка, называемую C++/CLI от Common Language Infrastructure. В общем, это расширение C++ под платформу .Net.

Рассмотрим в конце несколько примеров, чтобы лучше понять работу со случайными числами.

Заключение

Любые технологии и методы постоянно развиваются и совершенствуются. Так случилось и с механизмом генерации случайных чисел rand(), который устарел и перестал удовлетворять современным требованиям. В STL существует библиотека random, в .Net Framework — класс Random для работы со случайными числами. От использования rand следует отказываться в пользу новых методов, т. к. они соответствуют современным парадигмам программирования, а старые методы будут выводиться из стандарта.

Как пользоваться rand в c++ для генерации случайных чисел диапазона (-10,10).

/server/olimp/matrix# ./matrix
1726049282
-241251474
-725882838
-67000078
500250186
-105167902
1512805822
-1364528538
-954568918
-1976975366
-970789250
1239996754
-1512495394
575564690
-2051717710
695572846
1533807014
742897438
1786816134
299310934
вот что получилось Александр
а должно быть чтото типо
-1
0
-9
9
3
1
2

IT Novella

Для генерации псевдослучайных чисел в C++ используется функция

, которая возвращает случайное число из диапазона от 0 до RAND_MAX (RAND_MAX — константа, определенная в cstdlib. Значение зависит от версии библиотеки. В стандартных реализациях это значение больше или равно 32767.)

Для получения значения RAND_MAX можно использовать команду

На практике очень часто требуется генерировать число из диапазона от 0 до N.

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

Например, для получения числа из отрезка от 0 до 9, можно использовать выражение

Для получения числа из отрезка от a до b можно использовать выражение

возвращает значение от 1 до 10.

При повторном запуске программы функция rand() возвращает тоже самое значение.

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

Для этого используется функция

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

Например, используя фрагменты кода

будем получать два различных псевдослучайных числа из диапазона от 0 до 9.

Для автоматического изменения параметра seed при каждом запуске программы часто используют значение системного времени. Для этого применяется функция time(0) из библиотеки ctime

Например, приведенный ниже код генерирует новый набор случайных значений для переменных a,b,c из отрезка от 1 до 100 при каждом запуске программы

Понравилась статья? Поделиться с друзьями:
Все языки программирования для начинающих