C++ で範囲内の乱数を生成する
この記事では、指定した数値間隔で乱数を生成する方法について、複数の C++ の方法を紹介します。
C++11 <random>
ライブラリを使用して範囲内の乱数を生成する
C++ では、C++11 のリリースに伴い、乱数生成のための標準ライブラリ機能が新しいヘッダ <random>
の下に追加されました。<random>
ヘッダーが提供する RNG ワークフロー機能は、ランダムエンジンと分布の 2つの部分に分かれています。ランダムエンジンは予測不可能なビットストリームを返す役割を担っています。ディストリビューションは、一様分布、正規分布、その他の確率分布を満たす乱数(ユーザが指定した型)を返します。
最初に、ユーザはランダムエンジンをシード値で初期化しなければなりません。非決定論的ランダムビットのシステム固有のソースである std::random_device
を用いてエンジンをシードすることが推奨されます。これにより、エンジンは実行ごとに異なるランダムビットストリームを生成することができます。一方、ユーザが複数のプログラムを実行する際に同じシーケンスを生成する必要がある場合、ランダムエンジンは定数 int
リテラルで初期化されなければなりません。
次に、乱数が生成される区間の最小/最大値の引数を用いて分布オブジェクトを初期化します。以下の例では、uniform_int_distribution
を用いて 10 個の整数を任意にコンソールに出力しています。
#include <iostream>
#include <random>
using std::cout;
using std::endl;
constexpr int MIN = 1;
constexpr int MAX = 100;
constexpr int RAND_NUMS_TO_GENERATE = 10;
int main() {
std::random_device rd;
std::default_random_engine eng(rd());
std::uniform_int_distribution<int> distr(MIN, MAX);
for (int n = 0; n < RAND_NUMS_TO_GENERATE; ++n) {
cout << distr(eng) << "; ";
}
cout << endl;
return EXIT_SUCCESS;
}
出力:
57; 38; 8; 69; 5; 27; 65; 65; 73; 4;
<random>
ヘッダーは、異なるアルゴリズムと効率性のトレードオフを持つ複数のランダムエンジンを提供します。したがって、次のコードサンプルに示すように、特定のランダムエンジンを初期化することができます。
#include <iostream>
#include <random>
using std::cout;
using std::endl;
constexpr int MIN = 1;
constexpr int MAX = 100;
constexpr int RAND_NUMS_TO_GENERATE = 10;
int main() {
std::random_device rd;
std::mt19937 eng(rd());
std::uniform_int_distribution<int> distr(MIN, MAX);
for (int n = 0; n < RAND_NUMS_TO_GENERATE; ++n) {
cout << distr(eng) << "; ";
}
cout << endl;
return EXIT_SUCCESS;
}
出力:
59; 47; 81; 41; 28; 88; 10; 12; 86; 7;
範囲内の乱数を生成するために rand
関数を使用する
rand
関数は C 標準ライブラリの一部であり、C++ のコードから呼び出すことができます。高品質の乱数生成に rand
関数を使用することは推奨されないが、配列や行列を任意のデータで埋めるために利用することができます。この例では、この関数は 0 から MAX
の数値間隔の間の乱数を生成します。この関数は、複数回の実行で異なる値を生成するために、std::srand
(できれば現在の時刻を std::time(nullptr)
で渡す) で種付けしなければならないことに注意してください。
#include <ctime>
#include <iostream>
#include <random>
using std::cout;
using std::endl;
constexpr int MIN = 1;
constexpr int MAX = 100;
constexpr int RAND_NUMS_TO_GENERATE = 10;
int main() {
std::srand(std::time(nullptr));
for (int i = 0; i < RAND_NUMS_TO_GENERATE; i++) cout << rand() % MAX << "; ";
cout << endl;
return EXIT_SUCCESS;
}
出力:
36; 91; 99; 40; 3; 60; 90; 63; 44; 22;