Qt/C++ — Урок 074. Генерация псевдослучайных чисел с использованием случайной библиотеки STD

Пожалуйста, приостановите работу AdBlock на этом сайте.

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

Пример: Определение победителя в конкурсе репостов.

Имеется список из 53 человек. Необходимо выбрать из них победителя. Если вы выберете его самостоятельно, то вас могут обвинить в предвзятости. Поэтому вы решили написать программу. Она будет работать следующим образом. Вы вводите количество участников N, после чего программа выводит одно число – номер победителя.

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

Функция rand().

Данная функция возвращает случайное целое число в диапазоне от нуля до RAND_MAX. RAND_MAX это специальная константа языка Си, в которой содержится максимальное целое число, которое может быть возвращено функцией rand().

Функция rand() определена в заголовочном файле stdlib.h. Поэтому, если хотите использовать rand в своей программе, не забудьте подключить этот заголовочный файл. Константа RAND_MAX тоже определена в этом файле. Вы можете найти этот файл у себя на компьютере и посмотреть её значение.

Давайте посмотрим на эту функцию в действии. Запустим следующий код:

Листинг 1.

Должно получиться что-то вроде этого.

image

Рис.1 Пять случайных чисел, сгенерированных функцийе rand

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

Ограничить случайные числа сверху.

Кто в школе ждал момента, когда ему пригодится математика, приготовьтесь. Этот момент наступил. Чтобы ограничить сверху случайные числа, можно воспользоваться операцией получения остатка от деления, которую вы изучили в прошлом уроке. Наверное вы знаете, что остаток от деления на числа K всегда меньше числа K. Например, при делении на 4 могут получиться остатки 0, 1, 2 и 3. Поэтому если вы хотите ограничить сверху случайные числа числом K, то просто возьмите остаток от деления на K. Вот так:

Листинг 2.

image

Рис.2 Пять случайных чисел меньше 100

Ограничить числа снизу.

Функция rand возвращает случайные числа из отрезка [0, RAND_MAX]. А что если нам нужны только числа большие числа M (например, 1000)? Как быть? Всё просто. Просто прибавим к тому, что вернула функция rand, наше значение M. Тогда если функция вернёт , итоговый ответ будет M, если 2394, то итоговый ответ будет M + 2394. Этим действием мы как бы сдвигаем все числа на M единиц вперёд.

Задать границы функции rand сверху и снизу.

Например, получить числа от 80 до 100. Кажется, нужно просто объединить два способа, которые приведены выше. Получим что-то вроде этого:

Листинг 3.

Попробуйте запустить эту программу. Удивлены?

Да, такой способ работать не будет. Давайте прокрутим эту программу руками, чтобы убедиться в том, что мы допустили ошибку. Допустим rand() вернула число 143. Остаток от деления на 100 равен 43. Дальше 80 + 43 = 123. Значит такой способ не работает. Подобная конструкция выдаст числа от 80 до 179.

Давайте разберём по действиям наше выражение. rand()%100 может выдать числа от до 99 включительно. Т.е. из отрезка [0; 99]. Операция + 80 сдвигает наш отрезок на 80 единиц вправо. Получаем [80; 179]. Как видим, проблема у нас заключается в правой границе отрезка, она сдвинута вправо на 79 единиц. Это наше исходное число 80 минус 1. Давайте наведём порядок и сдвинем правую границу назад: 80 + rand()%(100 — 80 + 1). Тогда всё должно сработать как надо.

В общем случае если нам нужно получить числа из отрезка [A;B], то необходимо воспользоваться следующей конструкцией: A + rand()%(B-A+1).

Согласно этой формуле перепишем нашу последнюю программу:

Листинг 4.

Результат работы:

Рис.3 Случайные числа из диапазона [80;100]

Ну вот, теперь вы можете решить исходную задачу урока. Сгенерировать число из отрезка [1; N]. Или не можете?

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

Функция srand().

Да, каждый раз появляются одни и те же одинаковые числа. «Так себе генератор!» – скажете вы. И будете не совсем правы. Действительно, генерируются всё время одинаковые числа. Но мы можем на это повлиять, для этого используется функция srand(), которая также определена в заголовочном файле stdlib.h. Она инициализирует генератор случайных чисел начальным числом.

Скомпилируйте и запустите несколько раз вот эту программу:

Листинг 5.

Теперь поменяйте аргумент функции srand() на другое число (надеюсь вы ещё не забыли, что такое аргумент функции?) и снова скомпилируйте и запустите программу. Последовательность чисел должна измениться. Как только мы меняем аргумент в функции srand – меняется и последовательность. Не очень практично, не правда ли? Чтобы изменить последовательность, нужно перекомпилировать программу. Вот бы это число туда подставлялось автоматически.

И это можно сделать. Например, воспользуемся функцией time(), которая определена в заголовочном файле time.h. Данная функция, если ей в качестве аргумента передать NULL, возвращает количество секунд, прошедших c 1 января 1970 года. Вот посмотрите, как это делается.

Листинг 6.

Вы спросите, а что такое NULL? Резонный вопрос. А я вам пока отвечу, что это специальное зарезервированное слово такое. Могу ещё сказать, что им обозначает нулевой указатель, но т.к. это для вас никакой информации не несёт, то на данный момент рекомендую об этом не думать. А просто запомнить как некоторый хитрый трюк. В будущих уроках мы остановимся на этой штуке поподробнее.

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

Случайное число
65
Ссылка на результат:
Количество чисел:
 
Диапазон случайных чисел:
от до
 
Упорядочить:
 
Разделитель чисел:
 
 

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

Генератор чисел онлайн (рандомайзер) инструкция:

В генератор случайных чисел по умолчанию вводится 1 число. Если изменить настройки приложения, то можно одновременно генерировать до 250 случайных цифр. Для начала необходимо задать диапазон. Максимальное значение числа составляет 9 999 999 999. Генератор случайных чисел позволяет упорядочить числа по убыванию, возрастанию или же в случайном порядке.

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

Для отображения полученного результата можно использовать разные разделители: точку с запятой, запятую, а также пробел. Кроме того, возможно появление повторов. От дубляжей позволит избавиться опция «Исключить повторы». Также можно отправить ссылку на произведенные расчеты по мессенджеру или е-мейлу, скопировав «Ссылку на результат».

castlots.org ГЕНЕРАТОР СЛУЧАЙНЫХ ЧИСЕЛ онлайнСлучайное число:

Онлайн генератор случайных чисел или «Рандомайзер» — удобный сервис, который позволяет сгенерировать число или последовательность случайных чисел из заданного диапазона. Для того, чтобы получить случайное число:

  • укажите количество чисел (от 1 до 100);
  • задайте диапазон, например, от 1 до 10;
  • сгенерируйте число или последовательность.

Cфер примененияe у рандомайзера очень много: настольные игры, казино, букмекерские конторы, конкурсы и т.д. Мы очень надеемся, что наш генератор чисел будет Вам полезен!

Интересные статьи по теме рандом чисел: Генератор случайных чисел для лотерей — Генератор случайных чисел для конкурса

Я думаю понятие случайных чисел/величин вам знакомо: они случайны. Иногда в самодельном устройстве бывает нужна случайная величина, например для какой-нибудь игры или световых эффектов. Программный источник настоящих случайных чисел организовать весьма непросто, в отличие от аппаратного. Банально игральный кубик или лото-машина являются вполне себе хорошими источниками случайных чисел. Микроконтроллер к слову не может генерировать случайные числа, потому что он – точное вычислительное устройство, случайностей быть не может. Что делать? Использовать такое понятие, как псевдослучайные числа. Чем они отличаются от случайных? Своей природой. Псевдослучайное число получается путём различных математических действий с начальным числом, то есть имея начальное число, мы можем сгенерировать на его основе целую кучу других чисел. Но тут есть две проблемы:

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

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

  • random(max); – возвращает псевдослучайное число в диапазоне от 0 до (max – 1). max принимает unsigned long, то есть от 0 до 4 294 967 295
  • random(min, max); – возвращает псевдослучайное число в диапазоне от min до (max – 1). max принимает unsigned long, то есть от 0 до 4 294 967 295
  • randomSeed(value); – дать генератору псевдослучайных чисел новую опорную точку для отсчёта. value – любое число типа unsigned long, значит на Ардуино мы имеем 2^32 (4 294 967 295) наборов псевдослучайных чисел. На ваш век этого точно хватит!

Как правильно генерировать случайные числа, чтобы последовательность каждый раз была новая? Есть варианты:

  • При запуске программы задавать случайное число в randomSeed(). Как это сделать? Расскажу ниже
  • Если устройство как-то взаимодействует со внешним миром, или даже с пользователем, то можно при наступлении некоторых аппаратно случайных событий (нажатие кнопки, срабатывание датчика, принятие данных, и т.д.) скармливать randomSeed‘у текущее время с момента старта программы, т.е. функции millis() или micros(). Отличное решение кстати! Банально вызываем randomSeed(micros()) и всё.

Помните, в уроке про цифровые пины я говорил, что если пин никуда не подключен – то он ловит “из воздуха” всякие наводки. Шумы имеют природу, близкую к случайной, и было бы глупо этим не воспользоваться! Давайте посмотрим, какие значения можно получить с никуда не подключенного аналогового пина, опрашивая его обычным analogRead();

void loop() {    Serial.println(analogRead(A0));    delay(100);  }

  Синусоида? Вполне логично, в стенах куча проводов с сетевым напряжением, вот они и наводят на микроконтроллер всякие помехи. Можно ли пользоваться сырым значением с аналогового пина в качестве “зерна” для randomSeed()? Нужно! То есть при запуске устройства делать вот так:

void setup() {    // точка отсчёта для генератора случайных чисел    // А0 никуда не подключен    randomSeed(analogRead(A0));  }

Но есть ещё интересный вариант, который позволит получить гораздо более случайные числа для randomSeed().  Есть информация, что первые два бита из результата analogRead() имеют самый большой шум. Давайте на него посмотрим, выведя несколько (300) результатов в график. Получить первые два бита можно так: analogRead(A0) & 0b0000011, или более коротко – analogRead(A0) & 3

for (int i = 0; i < 300; i++) {      Serial.println(analogRead(A0) & 3);  }

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

unsigned long seed = 0;  // 16 раз  for (int i = 0; i < 16; i++) {    seed *= 4;    seed += analogRead(A0) & 3;  }  // скормить генератору случ. чисел  randomSeed(seed);

Именно такой код я рекомендую использовать для получения случайного зерна для генератора случайных чисел при запуске программы. Напоследок давайте посмотрим, какой результат даёт такая конструкция:

unsigned long seed;  for (int i = 0; i < 400; i++) {    seed = 1;    for (byte j = 0; j < 16; j++) {      seed *= 4;      seed += analogRead(A0) & 3;    }    Serial.println(seed);  }

График я построил в excel, чтобы более чётко видеть рассеивание полученного случайного значения   Имеем практически равномерное рассеяние и огромное количество случайных значений, полученных путём перемножения и сложения “шума”. Пользуйтесь на здоровье.

Иногда бывает нужен случайный флаг, то есть true/false. Делается это очень просто: в уроке про условия я рассказывал, что bool (boolean) принимает true при любом отличном от нуля значении. Это можно использовать для получения случайного true/false с заданной вероятностью! Просто присваиваем логической переменной результат функции random(), в которую передаём число, обратное вероятности получения false:

bool rndFlag = random(5);

Переменная rndFlag получит значение false с вероятностью 1/5, то есть 20%. Если нужен true с низкой вероятностью – используем инверсию:

bool rndFlag = !random(10);

Теперь переменная rndFlag получит значение true с вероятностью 10%.

  • Набор GyverKIT – большой стартовый набор Arduino моей разработки, продаётся в России
  • Каталог ссылок на дешёвые Ардуины, датчики, модули и прочие железки с AliExpress у проверенных продавцов
  • Подборка библиотек для Arduino, самых интересных и полезных, официальных и не очень
  • Полная документация по языку Ардуино, все встроенные функции и макро, все доступные типы данных
  • Сборник полезных алгоритмов для написания скетчей: структура кода, таймеры, фильтры, парсинг данных
  • Видео уроки по программированию Arduino с канала “Заметки Ардуинщика” – одни из самых подробных в рунете
  • Поддержать автора за работу над уроками
  • Обратная связь – сообщить об ошибке в уроке или предложить дополнение по тексту (alex@alexgyver.ru)

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

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

Функция случайного числа в Excel

  1. Функция СЛЧИС возвращает случайное равномерно распределенное вещественное число. Оно будет меньше 1, больше или равно 0.
  2. Функция СЛУЧМЕЖДУ возвращает случайное целое число.

Рассмотрим их использование на примерах.

Выборка случайных чисел с помощью СЛЧИС

Данная функция аргументов не требует (СЛЧИС()).

Чтобы сгенерировать случайное вещественное число в диапазоне от 1 до 5, например, применяем следующую формулу: =СЛЧИС()*(5-1)+1.

Возвращаемое случайное число распределено равномерно на интервале [1,10].

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

  1. Щелкаем по ячейке со случайным числом.
  2. В строке формул выделяем формулу.
  3. Нажимаем F9. И ВВОД.

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

  1. Сформируем «карманы». Диапазоны, в пределах которых будут находиться значения. Первый такой диапазон – 0-0,1. Для следующих – формула =C2+$C$2.
  2. Определим частоту для случайных чисел в каждом диапазоне. Используем формулу массива {=ЧАСТОТА(A2:A201;C2:C11)}.
  3. Сформируем диапазоны с помощью знака «сцепления» (=»[0,0-«&C2&»]»).
  4. Строим гистограмму распределения 200 значений, полученных с помощью функции СЛЧИС ().

Диапазон вертикальных значений – частота. Горизонтальных – «карманы».

Функция СЛУЧМЕЖДУ

Синтаксис функции СЛУЧМЕЖДУ – (нижняя граница; верхняя граница). Первый аргумент должен быть меньше второго. В противном случае функция выдаст ошибку. Предполагается, что границы – целые числа. Дробную часть формула отбрасывает.

Пример использования функции:

Случайные числа с точностью 0,1 и 0,01:

Как сделать генератор случайных чисел в Excel

Сделаем генератор случайных чисел с генерацией значения из определенного диапазона. Используем формулу вида: =ИНДЕКС(A1:A10;ЦЕЛОЕ(СЛЧИС()*10)+1).

Сделаем генератор случайных чисел в диапазоне от 0 до 100 с шагом 10.

Из списка текстовых значений нужно выбрать 2 случайных. С помощью функции СЛЧИС сопоставим текстовые значения в диапазоне А1:А7 со случайными числами.

Воспользуемся функцией ИНДЕКС для выбора двух случайных текстовых значений из исходного списка.

Чтобы выбрать одно случайное значение из списка, применим такую формулу: =ИНДЕКС(A1:A7;СЛУЧМЕЖДУ(1;СЧЁТЗ(A1:A7))).

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

Функции СЛЧИС и СЛУЧМЕЖДУ выдают случайные числа с единым распределением. Любое значение с одинаковой долей вероятности может попасть в нижнюю границу запрашиваемого диапазона и в верхнюю. Получается огромный разброс от целевого значения.

Нормальное распределение подразумевает близкое положение большей части сгенерированных чисел к целевому. Подкорректируем формулу СЛУЧМЕЖДУ и создадим массив данных с нормальным распределением.

Себестоимость товара Х – 100 рублей. Вся произведенная партия подчиняется нормальному распределению. Случайная переменная тоже подчиняется нормальному распределению вероятностей.

При таких условиях среднее значение диапазона – 100 рублей. Сгенерируем массив и построим график с нормальным распределением при стандартном отклонении 1,5 рубля.

Используем функцию: =НОРМОБР(СЛЧИС();100;1,5).

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

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

  1. Определим минимальное и максимальное значение в диапазоне с помощью функций МИН и МАКС.
  2. Укажем величину каждого периода либо шаг. В нашем примере – 1.
  3. Количество категорий – 10.
  4. Нижняя граница таблицы с категориями – округленное вниз ближайшее кратное число. В ячейку Н1 вводим формулу =ОКРВНИЗ(E1;E5).
  5. В ячейке Н2 и последующих формула будет выглядеть следующим образом: =ЕСЛИ(G2;H1+$E$5;»»). То есть каждое последующее значение будет увеличено на величину шага.
  6. Посчитаем количество переменных в заданном промежутке. Используем функцию ЧАСТОТА. Формула будет выглядеть так:

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

График с нормальным распределением готов. Как и должно быть, по форме он напоминает колокол.

Сделать то же самое можно гораздо проще. С помощью пакета «Анализ данных». Выбираем «Генерацию случайных чисел».

О том как подключить стандартную настройку «Анализ данных» читайте здесь.

Заполняем параметры для генерации. Распределение – «нормальное».

Жмем ОК. Получаем набор случайных чисел. Снова вызываем инструмент «Анализ данных». Выбираем «Гистограмма». Настраиваем параметры. Обязательно ставим галочку «Вывод графика».

Получаем результат:

Скачать генератор случайных чисел в Excel

График с нормальным распределением в Excel построен.

Оцените статью
Рейтинг автора
4,8
Материал подготовил
Максим Коновалов
Наш эксперт
Написано статей
127
А как считаете Вы?
Напишите в комментариях, что вы думаете – согласны
ли со статьей или есть что добавить?
Добавить комментарий