0Pricing
C++ Academy · 课时

正确设定随机种子

获得可复现的随机性

正确设定随机种子 是 CoddyKit 上的免费 C++ Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 C++ Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 C++ Academy 课程共包含 4 节课。

什么是播种

seed是引擎的初始状态。相同的 seed 会生成相同的序列,不同的 seed 会生成不同的序列。

#include <iostream>
#include <random>

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

用于可复现性的固定 seed

固定的 seed 会使结果可重复,非常适合测试和调试。

#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::随机设备

std::random_device从操作系统提供非确定性的 seed。使用它为引擎设置一次 seed。

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

设置一次 seed,重复使用

在启动时只设置一次 seed。每次生成值之前重新设置 seed 会破坏随机性质量。

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

时间 seed 的陷阱

使用time(nullptr)设置 seed 时,每秒只会变化一次,因此同时启动的程序会得到相同的序列。请优先使用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;
}

使用种子序列播种

引擎拥有大量内部状态。std::seed_seq会将多个 seed 值分散到全部内部状态中,从而实现更好的初始化。

#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收集多个值并放入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

您可以使用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具有非确定性,需要复现运行结果时绝不要使用它。此时请使用固定的 seed。

#include <iostream>
#include <random>

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

可复用的生成器

一种常见模式是将已设置 seed 的引擎封装在一个小型辅助工具后面,这样其余代码只需请求数字即可。

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

快速检查

测试您对播种的理解。

回顾

您了解了正确的播种方式:

  • 固定 seed可以得到可复现的运行结果;std::random_device可以提供唯一的运行结果
  • 在启动时设置一次 seed,而不是每次生成值时设置;避免使用精度较低的time() seed
  • seed_seq会将熵分散到整个引擎中,而且可以通过流保存和恢复引擎状态

接下来,您将把这些知识应用到实际示例中。

常见问题解答

「正确设定随机种子」课时是免费的吗?

是的 — 「正确设定随机种子」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 C++ Academy 课程的其余内容,请升级到 CoddyKit PRO。 C++ Academy 课程共包含 4 节课。

「正确设定随机种子」这节课中我会学到什么?

获得可复现的随机性 你通过在浏览器中直接运行的动手代码来练习 C++ Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 C++ Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 C++ Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。

「正确设定随机种子」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 C++ Academy 课中编写并运行代码吗?

能。每节 C++ Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 随机引擎
  2. 分布
  3. 正确设定随机种子
  4. 实践示例
← 返回 C++ Academy