0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

自作の乱数生成器を乱数分布ライブラリ(std::uniform_int_distribution)で加工する

Posted at

概要

独自のアルゴリズムで乱数生成器を作成し、標準の乱数分布と組み合わせて使用する方法を実践的に説明する。

環境

macOS 15.1
Xcode 16.1

C++ コンパイラのフラグを設定する

以下の内容の Makefile を用意する。

CXXFLAGS = -g -std=c++20 -O0 -Wall -Wextra --pedantic-errors

乱数分布ライブラリで乱数を望みの範囲に加工する

ファイル名 main.cpp で以下の内容を保存する。

#include <iostream>
#include <random>

int main() {
    std::uniform_int_distribution<int> d(1, 6);
    std::default_random_engine e;

    for (auto i = 0; i != 10; ++i) {
        std::cout << d(e) << " ";
    }
}

実行する

$ make main && ./main

実行結果は以下の様になる。
実行結果は環境によって異なるだろう。

2 6 5 1 3 1 1 3 3 3 

乱数生成器を自作する

先のファイルの先頭に以下の内容を追加する。
RandomEngine は、線形合同法(Linear Congruential generator)を実装している。

class RandomEngine
{
public:
    using result_type = unsigned int;
private:
    unsigned int a = 3;
    unsigned int x;
    unsigned int c = 5;
    // int m;
public:
    RandomEngine(unsigned int seed = 0) : x(seed) {}
    result_type operator()() {
        x = a * x + c;
        return x;
    }
    static constexpr result_type min() {
        return 0;
    }
    static constexpr result_type max() {
        return UINT_MAX;
    }
};

ここで RandomEngine::result_type が非負で定義されていることに注意。

LLVM のサブプロジェクトlibc++ による C++ 標準ライブラリの実装では、 std::uniform_int_distribution のオブジェクトが引き受ける乱数生成器について、非負の乱数を生成することを求めている。

詳しくは、libc++ プロジェクトの include/__random/is_valid.h で定義されている __libcpp_random_is_valid_urng を参照のこと。

先のプログラムにて自作した乱数生成器に置き換える

#include <iostream>
#include <random>

int main() {
    std::uniform_int_distribution<int> d(1, 6);
    RandomEngine e; // <- 置き換えた

    for (auto i = 0; i != 10; ++i) {
        std::cout << d(e) << " ";
    }
}

実行する

$ make main && ./main

実行結果は以下の様になる。
実行結果は環境によって異なるだろう。

6 5 2 1 6 5 2 1 6 5 
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?