C/C++で正規分布に従う乱数を生成する方法
本記事では、正規分布(ガウス分布)に従う乱数をC/C++で生成する方法を解説します。正規乱数は、Box-Muller法と呼ばれる変換公式を使うことで、一様乱数から簡単に求められます。その公式は次の通りです。
𝑧 = √−2 ln 𝑥1 cos (2𝜋𝑥2)
ここで、x1 と x2 はそれぞれ「0以上1未満」の範囲でランダムに選ばれた一様乱数です。この式によって得られる z は、平均0・標準偏差1の標準正規分布に従います。
サンプルコード
以下は、この公式を実装したC++のプログラム例です。生成した標準正規乱数に標準偏差(sigma)を掛け、平均値(Mi)を加算することで、任意の平均・分散を持つ正規乱数を作っています。
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <iostream>
using namespace std;
// 0以上1未満の一様乱数を返す
double rand_gen() {
return ((double)(rand()) + 1.) / ((double)(RAND_MAX) + 1.);
}
// 正規分布に従う乱数を返す(Box-Muller法)
double normalRandom() {
double v1 = rand_gen();
double v2 = rand_gen();
return cos(2 * 3.14 * v2) * sqrt(-2. * log(v1));
}
int main() {
double sigma = 82.0; // 標準偏差
double Mi = 40.0; // 平均値
for (int i = 0; i < 20; i++) {
double x = normalRandom() * sigma + Mi;
cout << " x = " << x << endl;
}
}実行結果
x = 1.91628 x = 57.0448 x = 51.4348 x = 53.5612 x = -83.8511 x = -28.9197 x = -76.0576 x = 62.1435 x = 23.9 x = -87.0663 x = 50.6942 x = 94.1685 x = -88.1597 x = 168.502 x = 40.7563 x = 90.1091 x = 16.9218 x = -36.9178 x = 135.969 x = 56.8888
コードのポイント
rand_gen()関数:rand()が返すのは0〜RAND_MAXの整数値のため、これをRAND_MAX+1で割ることで0以上1未満の実数に変換しています。分子に1を加えているのは、v1が0になるとlog(0)が計算できなくなる(マイナス無限大になる)ことを防ぐためです。
normalRandom()関数:2つの一様乱数v1、v2を用いてBox-Muller変換を行い、標準正規分布に従う値を返します。
sigma と Mi:標準正規乱数に対して「×標準偏差 + 平均値」という線形変換を施すことで、平均Mi・標準偏差sigmaの正規分布に従う乱数へと調整できます。
補足:より実用的な使い方
上記のコードではsrand()を呼び出していないため、毎回同じ乱数列が生成されます。実行ごとに異なる結果が必要な場合は、main関数の先頭で srand(time(NULL)); を呼び出してください。
また、C++11以降では <random> ヘッダーの std::normal_distribution を使えば、より高品質な正規乱数を簡単に生成できます。自前実装は学習目的やレガシー環境向けと考え、実務では標準ライブラリの活用を推奨します。
-
Pythonで疑似乱数を生成する方法|randomモジュールの使い方を徹底解説
多くのコンピュータアプリケーションでは、乱数の生成が必要になります。しかし、コンピュータが生成できるのは「真の乱数」ではなく、あくまで規則性に基づいた疑似乱数です。 Pythonも他のプログラミング言語と同様に疑似乱数ジェネレーターを使用しており、その基盤となっているのは「メルセンヌ・ツイスタ(Mersenne Twister)」というアルゴリズムです。このアルゴリズムは53ビット精度の浮動小数点数を生成し、高速かつスレッドセーフであることが特徴ですが、暗号化用途には適していません。 Pythonの標準ライブラリには random モジュールが含まれており、乱数を扱うためのさまざまな関数が定義
-
PythonのNumPyで乱数を生成する方法を徹底解説
NumPyパッケージには、乱数の生成に役立つさまざまな関数が含まれた random モジュール が用意されています。この記事では、特に利用頻度の高い rand()、randn()、randint()、random() の4つの関数について、実際のコード例とともにわかりやすく解説します。 numpy.random.rand():一様分布の乱数配列を作成する numpy.random.rand() は、指定した形状(シェイプ)の配列を作成し、その要素を「0以上1未満」の一様分布から抽出されたランダムなサンプルで満たします。引数に配列の次元サイズを渡します。 >>> import