0Pricing
C++ Academy · 课时

随机引擎

生成随机位

随机引擎 是 CoddyKit 上的免费 C++ Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 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;
}

复用一个引擎

创建一个引擎,并在程序中的所有随机操作中复用它。每次都创建新引擎既浪费资源,也可能降低质量。

#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 是确定性的首选引擎
  • 复用一个引擎,并正确设置种子,以获得真正的多样性

接下来,您将使用分布调整引擎输出的形状。

常见问题解答

「随机引擎」课时是免费的吗?

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

「随机引擎」这节课中我会学到什么?

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

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

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

「随机引擎」课时需要多长时间?

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

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

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

此课程中的所有课时

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