Чтение онлайн

на главную - закладки

Жанры

C++. Сборник рецептов

Когсуэлл Джефф

Шрифт:

Пример 11.10 иллюстрирует работу функции

accumulate
, показывая, как предоставленный пользователем функтор вызывается для каждого элемента последовательности.

Пример 11.10. Пример реализации функции accumulate

template<class Iter_T, class Value_T, class BinOp_T>

Iter_T accumulate(Iter_T begin, Iter_T end, Value_T value, BinOp_T op) {

 while (begin != end) {

value = op(value, *begin++)

 }

 return value;

}

11.6.

Генерация случайных чисел

Проблема

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

[0.0, 1.0)
при равномерном их распределении.

Решение

Стандарт C++ предусматривает наличие C-функции библиотеки этапа исполнения

rand
, определенной в заголовочном файле
<cstdlib>
, которая возвращает случайное число в диапазоне от 0 до
RAND_MAX
включительно. Макропеременная
RAND_MAX
представляет собой максимальное значение, которое может быть возвращено функцией
rand
. Пример 11.11 демонстрирует применение функции
rand
для генерации случайных чисел с плавающей точкой.

Пример 11.11. Генерация случайных чисел функцией rand

#include <cstdlib>

#include <ctime>

#include <iostream>

using namespace std;

double doubleRand {

 return double(rand) / (double(RAND_MAX) + 1.0);

}

int main {

 srand(static_cast<unsigned int>(clock));

 cout << "expect 5 numbers within the interval [0.0, 1.0)" << endl;

 for (int i=0; i < 5; i++) {

cout << doubleRand << "\n";

 }

 cout << endl;

}

Программа примера 11.11 должна выдать результат, подобный следующему.

expect 5 numbers within the interval [0.0, 1.0)

0.010437

0.740997

0.34906

0.369293

0.544373

Обсуждение

Необходимо уточнить, что функции, генерирующие случайные числа (в том числе

rand
), возвращают псевдослучайные числа, а не реальные случайные числа, поэтому там, где я говорю «случайное число», я на самом деле имею в виду псевдослучайное число.

Перед применением функции

rand
вы должны «посеять» (т.е. инициализировать) генератор случайных чисел с помощью вызова функции
srand
. Это обеспечивает генерацию последующими вызовами
rand
разных последовательностей чисел при каждом новом исполнении программы. Проще всего инициализировать генератор случайных чисел путем передачи ему результата вызова функции
clock
из заголовочного
файла
<ctime>
, имеющего тип
unsigned int
. Повторная инициализация генератора случайных чисел приводит к тому, что генерируемые числа становятся менее случайными.

Функция

rand
имеет много ограничений. Прежде всего, она генерирует только целые числа, и эти числа могут иметь только равномерное распределение. Более того, конкретный алгоритм генерации случайных чисел зависит от реализации, и поэтому последовательности случайных чисел нельзя воспроизвести при переходе от одной системы к другой при одинаковой инициализации. Это создает трудности для определенного типа приложений, а также при тестировании и отладке.

Значительно более изощренную альтернативу

rand
представляет написанная Джензом Маурером (Jens Maurer) библиотека Boost Random; она была инспирирована предложениями по генерации случайных чисел, представленными в TR1.

TR1 означает «Technical Report One» и представляет собой официальный проект по расширению стандартной библиотеки C++98.

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

[0,1)
.

Пример 11.12. Использование библиотеки Boost Random

#include <boost/random.hpp>

#include <iostream>

#include <cstdlib>

using namespace std;

using namespace boost;

typedef boost::mt19937 BaseGenerator;

typedef boost::uniform_real<double> Distribution;

typedef boost::variate_generator<BaseGenerator, Distribution> Generator;

double boostDoubleRand {

 static BaseGenerator base;

 static Distribution dist;

 static Generator rng(base, dist);

 return rng;

}

int main {

 cout << "expect 5 numbers within the interval [0.1)" << endl;

 for (int i=0; i < 5; i++) {

cout << boostDoubleRand << "\n";

 }

 cout << endl;

}

Основное преимущество библиотеки Boost Random в том, что алгоритм генерации псевдослучайных чисел обеспечивает гарантированные и воспроизводимые свойства случайных последовательностей, зависящих от выбранного алгоритма. В примере 11.12 я использую генератор Mersenne Twister (

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

Поделиться:
Популярные книги

Кротовский, не начинайте

Парсиев Дмитрий
2. РОС: Изнанка Империи
Фантастика:
городское фэнтези
попаданцы
альтернативная история
5.00
рейтинг книги
Кротовский, не начинайте

Вадбольский

Никитин Юрий Александрович
1. Вадбольский
Фантастика:
попаданцы
5.00
рейтинг книги
Вадбольский

Истребители. Трилогия

Поселягин Владимир Геннадьевич
Фантастика:
альтернативная история
7.30
рейтинг книги
Истребители. Трилогия

Законник Российской Империи. Том 4

Ткачев Андрей Юрьевич
4. Словом и делом
Фантастика:
городское фэнтези
альтернативная история
аниме
дорама
5.00
рейтинг книги
Законник Российской Империи. Том 4

Пятнадцать ножевых 4

Вязовский Алексей
4. 15 ножевых
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Пятнадцать ножевых 4

Адаптация

Уленгов Юрий
2. Гардемарин ее величества
Фантастика:
городское фэнтези
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Адаптация

Имперский Курьер. Том 4

Бо Вова
4. Запечатанный мир
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Имперский Курьер. Том 4

Его огонь горит для меня. Том 2

Муратова Ульяна
2. Мир Карастели
Фантастика:
юмористическая фантастика
5.40
рейтинг книги
Его огонь горит для меня. Том 2

Кодекс Крови. Книга VII

Борзых М.
7. РОС: Кодекс Крови
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга VII

Локки 4 Потомок бога

Решетов Евгений Валерьевич
4. Локки
Фантастика:
аниме
фэнтези
5.00
рейтинг книги
Локки 4 Потомок бога

Хозяйственная помощница для идеала

Свободина Виктория
15. Помощница
Любовные романы:
современные любовные романы
эро литература
5.00
рейтинг книги
Хозяйственная помощница для идеала

Газлайтер. Том 19

Володин Григорий Григорьевич
19. История Телепата
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Газлайтер. Том 19

Три `Д` для миллиардера. Свадебный салон

Тоцка Тала
Любовные романы:
современные любовные романы
короткие любовные романы
7.14
рейтинг книги
Три `Д` для миллиардера. Свадебный салон

Студиозус 2

Шмаков Алексей Семенович
4. Светлая Тьма
Фантастика:
юмористическое фэнтези
городское фэнтези
аниме
5.00
рейтинг книги
Студиозус 2