return value;
}
11.6. Генерация случайных чисел
Требуется сгенерировать несколько случайных чисел в формате с плавающей точкой в интервале значений [0.0, 1.0)
при равномерном их распределении.
Стандарт C++ предусматривает наличие C-функции библиотеки этапа исполнения rand
, определенной в заголовочном файле
, которая возвращает случайное число в диапазоне от 0 до RAND_MAX
включительно. Макропеременная RAND_MAX
представляет собой максимальное значение, которое может быть возвращено функцией rand
. Пример 11.11 демонстрирует применение функции rand
для генерации случайных чисел с плавающей точкой.
#include
#include
#include
using namespace std;
double doubleRand() {
return double(rand()) / (double(RAND_MAX) + 1.0);
}
int main() {
srand(static_cast
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
из заголовочного файла
, имеющего тип unsigned int
. Повторная инициализация генератора случайных чисел приводит к тому, что генерируемые числа становятся менее случайными.
Функция rand
имеет много ограничений. Прежде всего, она генерирует только целые числа, и эти числа могут иметь только равномерное распределение. Более того, конкретный алгоритм генерации случайных чисел зависит от реализации, и поэтому последовательности случайных чисел нельзя воспроизвести при переходе от одной системы к другой при одинаковой инициализации. Это создает трудности для определенного типа приложений, а также при тестировании и отладке.
Значительно более изощренную альтернативу rand
представляет написанная Джензом Маурером (Jens Maurer) библиотека Boost Random; она была инспирирована предложениями по генерации случайных чисел, представленными в TR1.
Библиотека Boost Random содержит несколько высококачественных функций по генерации случайных чисел как для целых типов, так и для типов с плавающей точкой, причем с поддержкой многочисленных распределений. Пример 11.12 показывает, как можно сгенерировать случайные числа с плавающей точкой в интервале значений [0,1)
.
#include
#include
#include
using namespace std;
using namespace boost;
typedef boost::mt19937 BaseGenerator;
typedef boost::uniform_real
typedef boost::variate_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;
}