samplingC++11

[機能]

  確率分布生成器,重み付き確率分布生成器,線形重み付き確率分布生成器を生成します.

[形式]
#include <random>
		// 確率分布生成器
template <class IntType = int> class discrete_distribution;
		// 重み付き確率分布生成器
template <class RealType = double> class piecewise_constant_distribution;
		// 線形重み付き確率分布生成器
template <class RealType = double> class piecewise_linear_distribution;		

[使用例]

  1. discrete_distribution,piecewise_constant_distribution,piecewise_linear_distribution の使用方法です.
    #include <iostream>
    #include <vector>
    #include <random>
    
    using namespace std;
    
    int main()
    {
    			// 乱数の初期設定
    	random_device sd;   // 予測不能な乱数生成器(class),初期設定のために使用
    	mt19937 rnd(sd());   // 乱数生成期の定義とその初期設定
    			// 確率分布生成器 [0.0, 0.3, 0.1, 0.1]
    	vector<double> v1 = {0.0, 0.3, 0.1, 0.1};   // 最初の値は必ず 0,等間隔
    	discrete_distribution<size_t> disc(v1.begin(), v1.end());   // コンストラクタ
    	cout << "確率分布生成器 [0.0, 0.3, 0.1, 0.1]\n";
    	vector<double> v2(3);
    	for (int i1 = 0; i1 < 1000; i1++) {
    		int n = disc(rnd) - 1;   // 入るべき区間番号が返る
    		v2[n]++;
    	}
    	for (int i1 = 0; i1 < 3; i1++) {
    		cout << "  " << v2[i1];
    		v2[i1] = 0;
    	}
    	cout << endl;
    			// 重み付き確率分布生成器 {0.0, 0.1, 0.2, 0.3}, {0.3, 0.1, 0.1}
    			// 区間 [0, 0.1) に入る確率 0.3
    			//      [0.1, 0.2) に入る確率 0.1
    			//      [0.2, 0.3) に入る確率 0.1
    	vector<double> v3 = {0.0, 0.1, 0.2, 0.3};   // 等間隔である必要は無い
    	vector<double> v4 = {0.3, 0.1, 0.1};   // 各区間に入る確率
    	piecewise_constant_distribution<> pie(v3.begin(), v3.end(), v4.begin());   // コンストラクタ
    	cout << "重み付き確率分布生成器 {0.0, 0.1, 0.2, 0.3}, {0.3, 0.1, 0.1}\n";
    	for (int i1 = 0; i1 < 1000; i1++) {
    		double x = pie(rnd);
    		bool sw  = false;
    		for (int i2 = 0; i2 < 2; i2++) {
    			if (x < v3[i2+1]) {
    				v2[i2]++;
    				sw = true;
    				break;
    			}
    		}
    		if (!sw)
    			v2[2]++;
    	}
    	for (int i1 = 0; i1 < 3; i1++) {
    		cout << "  " << v2[i1];
    		v2[i1] = 0;
    	}
    	cout << endl;
    			// 線形重み付き確率分布生成器 {0.0, 0.1, 0.2, 0.3}, {0.0, 0.3, 0.1, 0.1}
    			// 区間 [0, 0.1) に入る値の出現確率が0.0から0.3まで線形に上昇
    			//      [0.1, 0.2) に入る値の出現確率が0.3から0.1まで線形に減少
    			//      [0.2, 0.3) に入る値の出現確率が0.1
    				// {0.0, 0.1, 0.2, 0.3}, {0.0, 0.3, 0.1, 0.1} の場合
    	vector<double> v5 = {0.0, 0.1, 0.2, 0.3};   // 等間隔である必要は無い
    	vector<double> v6 = {0.0, 0.3, 0.1, 0.1};   // 確率
    	piecewise_linear_distribution<> pie_l1(v5.begin(), v5.end(), v6.begin());   // コンストラクタ
    	cout << "線形重み付き確率分布生成器 {0.0, 0.1, 0.2, 0.3}, {0.0, 0.3, 0.1, 0.1}\n";
    	for (int i1 = 0; i1 < 1000; i1++) {
    		double x = pie_l1(rnd);
    		bool sw  = false;
    		for (int i2 = 0; i2 < 2; i2++) {
    			if (x < v5[i2+1]) {
    				v2[i2]++;
    				sw = true;
    				break;
    			}
    		}
    		if (!sw)
    			v2[2]++;
    	}
    	for (int i1 = 0; i1 < 3; i1++) {
    		cout << "  " << v2[i1];
    		v2[i1] = 0;
    	}
    	cout << endl;
    				// {0.0, 0.1, 0.2, 0.3}, {0.1, 0.1, 0.1, 0.1} の場合,一様分布
    	vector<double> v7 = {0.0, 0.1, 0.2, 0.3};   // 等間隔である必要は無い
    	vector<double> v8 = {0.1, 0.1, 0.1, 0.1};   // 確率
    	piecewise_linear_distribution<> pie_l2(v7.begin(), v7.end(), v8.begin());   // コンストラクタ
    	cout << "線形重み付き確率分布生成器 {0.0, 0.1, 0.2, 0.3}, {0.1, 0.1, 0.1, 0.1}\n";
    	for (int i1 = 0; i1 < 1000; i1++) {
    		double x = pie_l2(rnd);
    		bool sw  = false;
    		for (int i2 = 0; i2 < 2; i2++) {
    			if (x < v7[i2+1]) {
    				v2[i2]++;
    				sw = true;
    				break;
    			}
    		}
    		if (!sw)
    			v2[2]++;
    	}
    	for (int i1 = 0; i1 < 3; i1++)
    		cout << "  " << v2[i1];
    	cout << endl;
    
    	return 0;
    }
    			
    (出力)
    確率分布生成器 [0.0, 0.3, 0.1, 0.1]
      606  198  196
    重み付き確率分布生成器 {0.0, 0.1, 0.2, 0.3}, {0.3, 0.1, 0.1}
      617  174  209
    線形重み付き確率分布生成器 {0.0, 0.1, 0.2, 0.3}, {0.0, 0.3, 0.1, 0.1}
      311  449  240
    線形重み付き確率分布生成器 {0.0, 0.1, 0.2, 0.3}, {0.1, 0.1, 0.1, 0.1}
      346  318  336			
[参照]

mt19937uniformBernoulliPoissonnormal

菅沼ホーム 本文目次 演習問題解答例 付録目次 索引