#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;
}