Gobble up pudding

プログラミングの記事がメインのブログです。

MENU

C++11から導入された乱数、randomの使い方

スポンサードリンク

f:id:fa11enprince:20200628233654j:plain
C言語のrand()関数はたとえシードを変えても精度がわるく、
規則性がある程度出てしまうというような話を聞いたことがあると思います。
このあたりの話になるとかなり難しい分野(少なくとも僕にとっては)なので、
リンク先に説明は譲ることとします。
C言語では乱数の生成は以下のようにしていたと思います。

C99のコード

#include <stdlib.h>
#include <stdio.h>
#include <time.h>

int main()
{
    // 現在時刻をシードとする
    srand((unsigned int)time(NULL));
    for (int i = 0; i < 20; i++)
    {
        // [0, 4]の乱数を生成
        printf("%d\n", rand() % 5);
    }

    return 0;
}

なるべくこれからはこれを使わず外部のライブラリや
アルゴリズムを使うべきだと思います。
しかしC++を使ってるのならば、C++11から使えるrandomがあります。
リファレンスを見てもハァなのですが、上記と同じような使い方であれば下記でOKです。
メルセンヌ・ツイスタ法というのを使います。

C++11のコード

#include <random>
#include <iostream>

int main()
{
    // 被決定的な乱数生成器でシード生成器を生成
    std::random_device rnd;
    // メルセンヌ・ツイスタ 引数は初期シード値 ファンクタを渡す
    std::mt19937 mt(rnd());
    std::uniform_int_distribution<int> rand5(0,4); // [0, 4]の一様乱数
    for (int i = 0; i < 20; i++)
    {
        std::cout << rand5(mt) << "\n";
    }
    return 0;
}