0Pricing
C++ Academy · レッスン

乱数エンジン

ランダムなビットを生成します

「乱数エンジン」はCoddyKit上の無料C++ Academyレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC++ Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C++ Academyコースには全4レッスンが含まれています。

なぜ<random>を使うのか

従来のrand()は品質が低く、制御も困難です。<random>ライブラリでは、乱数をエンジン(乱数ビットの生成元)と分布(出力の形)に分けて扱います。

#include <iostream>
#include <random>

int main() {
    std::mt19937 engine(42);
    std::cout << "engine produced a value\n";
    unsigned int v = engine();
    std::cout << (v != 0 ? "non-zero" : "zero") << '\n';
    return 0;
}

メルセンヌ・ツイスタ

std::mt19937は最も一般的なエンジンです。高速で品質が高く、周期も長いという特徴があります。数値はビット単位の状態サイズを表します。

#include <iostream>
#include <random>

int main() {
    std::mt19937 gen(1);
    unsigned int a = gen();
    unsigned int b = gen();
    std::cout << (a != b ? "two different values" : "same") << '\n';
    return 0;
}

エンジンは決定的に動作する

同じシードを与えると、エンジンは常に同じシーケンスを生成します。これにより結果を再現できます。

#include <iostream>
#include <random>

int main() {
    std::mt19937 a(123), b(123);
    std::cout << std::boolalpha << (a() == b()) << '\n';
    std::cout << (a() == b()) << '\n';
    return 0;
}

エンジンを呼び出す

エンジンは呼び出し可能なオブジェクトです。呼び出すたびに、engine()はその範囲内の次の生の乱数整数を返します。

#include <iostream>
#include <random>

int main() {
    std::mt19937 gen(7);
    for (int i = 0; i < 3; ++i) {
        unsigned int v = gen();
        std::cout << (v % 100) << ' ';
    }
    std::cout << '\n';
    return 0;
}

エンジンの範囲

min()とmax()は、エンジンが生成できる生の値の範囲を返します。

#include <iostream>
#include <random>

int main() {
    std::mt19937 gen;
    std::cout << "min: " << gen.min() << '\n';
    std::cout << "max: " << gen.max() << '\n';
    return 0;
}

その他のエンジン

ライブラリには、次のような複数のエンジンがあります。

  • minstd_rand:小規模な線形合同法ジェネレーターです。
  • mt19937:汎用のデフォルトエンジンです。
  • ranlux48:品質が高い一方、処理は低速です。
#include <iostream>
#include <random>

int main() {
    std::minstd_rand lcg(5);
    std::mt19937 mt(5);
    std::cout << (lcg() % 10) << ' ' << (mt() % 10) << '\n';
    return 0;
}

64ビットエンジン

大きなハッシュや広大な範囲など、64ビットの乱数値が必要な場合はstd::mt19937_64を使用します。

#include <iostream>
#include <random>

int main() {
    std::mt19937_64 gen(99);
    unsigned long long v = gen();
    std::cout << "got a 64-bit value: " << (v != 0 ? "yes" : "no") << '\n';
    return 0;
}

エンジンと分布の違い

エンジンの生の出力は、非常に広い範囲で一様に分布します。サイコロの出目のような実用的な値を得るには、エンジンを分布に渡します。

#include <iostream>
#include <random>

int main() {
    std::mt19937 gen(2024);
    std::uniform_int_distribution<int> die(1, 6);
    std::cout << "rolled " << die(gen) << '\n';
    return 0;
}

値を破棄する

discard(n)は出力を生成せずにエンジンをnステップ進めます。シーケンスを先に進めたい場合に便利です。

#include <iostream>
#include <random>

int main() {
    std::mt19937 a(10), b(10);
    b.discard(2);
    a(); a();
    std::cout << std::boolalpha << (a() == b()) << '\n';
    return 0;
}

1つのエンジンを再利用する

エンジンを1つだけ作成し、プログラム内のすべての乱数生成で再利用してください。毎回新しいエンジンを作成するのは非効率で、品質を低下させる可能性もあります。

#include <iostream>
#include <random>

int main() {
    std::mt19937 gen(2026);
    std::uniform_int_distribution<int> d10(1, 10);
    int total = 0;
    for (int i = 0; i < 5; ++i) total += d10(gen);
    std::cout << "sum of 5 rolls: " << total << '\n';
    return 0;
}

デフォルトシードの落とし穴

デフォルト構築したエンジンは固定されたデフォルトシードを使用するため、毎回同じシーケンスを生成します。本当に多様な結果を得るにはシードを設定する必要があります(次のレッスンで扱います)。

#include <iostream>
#include <random>

int main() {
    std::mt19937 gen; // default seed: same every run
    std::cout << "first value mod 1000: " << (gen() % 1000) << '\n';
    return 0;
}

クイックチェック

乱数エンジンについて理解度を確認しましょう。

まとめ

乱数エンジンについて、次のことを学びました。

  • <random>では、エンジン(ビットの生成元)と分布(出力の形)を分けて扱います
  • std::mt19937は定番のエンジンで、同じシードに対して決定的に動作します
  • 1つのエンジンを再利用し、適切にシードを設定して多様な結果を得ます

次は、分布を使ってエンジンの出力を整形します。

よくある質問

「乱数エンジン」レッスンは無料ですか?

はい。「乱数エンジン」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C++ Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C++ Academyコースには全4レッスンが含まれています。

「乱数エンジン」で何を学びますか?

ランダムなビットを生成します ブラウザで直接実行するハンズオンコードでC++ Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

C++ Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのC++ Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。

「乱数エンジン」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このC++ Academyレッスンでコードを書いて実行できますか?

はい。すべてのC++ Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 乱数エンジン
  2. 分布
  3. 適切なシード設定
  4. 実践例
← C++ Academyに戻る