0Pricing
C++ Academy · レッスン

適切なシード設定

再現可能な乱数を得ます

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

シードとは

シードは、エンジンの開始時の状態です。同じシードを使うと同じ系列を再現でき、異なるシードを使うと異なる系列になります。

#include <iostream>
#include <random>

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

再現性のための固定シード

定数のシードを使うと結果が再現可能になるため、テストやデバッグに適しています。

#include <iostream>
#include <random>

int main() {
    auto run = [](unsigned s) {
        std::mt19937 g(s);
        return g() % 1000;
    };
    std::cout << run(42) << ' ' << run(42) << '\n';
    return 0;
}

std::random_device

std::random_deviceは、オペレーティングシステムから非決定的なシードを提供します。これを1回使ってエンジンにシードを設定します。

#include <iostream>
#include <random>

int main() {
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_int_distribution<int> d(1, 6);
    std::cout << "a roll: " << d(gen) << '\n';
    return 0;
}

1回シードを設定して再利用

起動時にエンジンへ1回だけシードを設定します。値を生成するたびに再度シードを設定すると、乱数の品質が損なわれます。

#include <iostream>
#include <random>

int main() {
    std::random_device rd;
    std::mt19937 gen(rd());            // seed once
    std::uniform_int_distribution<int> d(1, 100);
    for (int i = 0; i < 3; ++i) std::cout << d(gen) << ' ';
    std::cout << '\n';
    return 0;
}

時刻をシードに使う際の注意点

time(nullptr)によるシードは1秒に1回しか変化しないため、同時に起動したプログラムは同じ系列を取得します。random_deviceを使用してください。

#include <iostream>
#include <random>
#include <ctime>

int main() {
    std::mt19937 gen(static_cast<unsigned>(std::time(nullptr)));
    std::cout << "seeded from time (coarse)\n";
    std::cout << (gen() % 100) << '\n';
    return 0;
}

seed_seqによるシード設定

エンジンには大量の内部状態があります。std::seed_seqは複数のシード値をその全体に分散させ、初期化の品質を高めます。

#include <iostream>
#include <random>

int main() {
    std::seed_seq seq{1, 2, 3, 4};
    std::mt19937 gen(seq);
    std::cout << (gen() % 1000) << '\n';
    return 0;
}

random_deviceの値を組み合わせる

高品質なシードを設定するには、random_deviceから複数の値を取得し、seed_seqにまとめます。

#include <iostream>
#include <random>
#include <array>

int main() {
    std::random_device rd;
    std::array<unsigned, 4> seeds{rd(), rd(), rd(), rd()};
    std::seed_seq seq(seeds.begin(), seeds.end());
    std::mt19937 gen(seq);
    std::cout << "well-seeded engine ready\n";
    std::cout << (gen() % 100) << '\n';
    return 0;
}

明示的な再シード

既存のエンジンは、seed(value)で既知の地点から系列を再開するようにリセットできます。

#include <iostream>
#include <random>

int main() {
    std::mt19937 gen(1);
    unsigned first = gen();
    gen.seed(1);             // restart
    std::cout << std::boolalpha << (gen() == first) << '\n';
    return 0;
}

状態の保存と復元

エンジンはストリームへ出力し、そこから再び入力できます。これにより、乱数の状態を正確に保存して再開できます。

#include <iostream>
#include <sstream>
#include <random>

int main() {
    std::mt19937 gen(5);
    std::ostringstream save; save << gen;
    unsigned expected = gen();
    std::istringstream load(save.str());
    std::mt19937 restored; load >> restored;
    std::cout << std::boolalpha << (restored() == expected) << '\n';
    return 0;
}

random_deviceは再現性がない

random_deviceは非決定的であるため、実行結果を再現する必要がある場合には決して使用しないでください。その場合は固定シードを使用します。

#include <iostream>
#include <random>

int main() {
    const unsigned FIXED = 2026;
    std::mt19937 gen(FIXED); // reproducible across runs
    std::cout << (gen() % 10000) << '\n';
    return 0;
}

再利用可能なジェネレーター

よく使われるパターンでは、シードを設定したエンジンを小さなヘルパーの背後に隠し、残りのコードからは数値を要求するだけにします。

#include <iostream>
#include <random>

int roll(std::mt19937& gen) {
    std::uniform_int_distribution<int> d(1, 6);
    return d(gen);
}

int main() {
    std::mt19937 gen(2026);
    std::cout << roll(gen) << ' ' << roll(gen) << '\n';
    return 0;
}

理解度チェック

シード設定についての理解度を確認します。

まとめ

適切なシード設定について学びました。

  • 固定シードを使うと実行結果を再現でき、std::random_deviceを使うと毎回異なる結果になります
  • シードは値を生成するたびではなく、起動時に1回だけ設定します。精度の粗いtime()によるシードは避けます
  • seed_seqはエントロピーをエンジン全体に分散させます。また、エンジンの状態はストリーム経由で保存・復元できます

次は、これらを実用的な例に適用します。

よくある質問

「適切なシード設定」レッスンは無料ですか?

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

「適切なシード設定」で何を学びますか?

再現可能な乱数を得ます ブラウザで直接実行するハンズオンコードでC++ Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

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

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

「適切なシード設定」レッスンにはどのくらい時間がかかりますか?

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

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

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

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

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