新闻详情

新闻详情

首页 / 资讯中心 / 详情

C++ STL 之随机数生成详解

发布时间:2026/9/10 13:07:43来源:尧图网络
C++ STL 之随机数生成详解
C STL 之随机数生成详解为什么 C 的rand()不该用C 标准库的rand()有三个硬伤周期极短绝大多数实现周期仅 231− 1约 21 亿在大量采样时必然重复。低位不随机rand() % n依赖低 12 位实现多为 LCG线性同余低位周期比高位短得多。例如RAND_MAX为 32767 时rand() % 2始终输出 0、1、0、1……无分布抽象rand() % n会产生偏差除非 n 整除 RAND_MAX更不存在正态、伯努利等分布。C11 的random用**引擎Engine 分布Distribution**双层架构彻底解决了这些问题。双层架构随机数引擎 Engine随机数分布 Distributionmt19937ranlux48knuth_buniform_int_distributionnormal_distributionbernoulli_distribution均匀分布整数正态分布浮点数伯努利分布布尔值引擎负责产生原始随机比特流分布将比特流映射为特定分布的数值。上层只关心分布下层只关心随机性——职责分离。引擎选型std::mt19937——梅森旋转算法最常用、最推荐。周期 219937− 1约 106000状态大小 2.5 KB。通过了绝大多数统计随机性测试Diehard、BigCrush。#includerandom#includeiostreamintmain(){std::mt19937eng(42);// 固定种子可复现std::couteng()\n;// 直接取原始 uint32_treturn0;}mt19937_64是 64 位版本周期相同输出uint64_t。std::ranlux48——RANLUX 算法源自物理学家 Lüscher 的提议通过丢弃部分输出改善相关性。周期约 2576状态小约 300 字节适合对统计质量要求极高、对速度不敏感的场合。std::ranlux48eng(42);std::knuth_b——Knuth 洗牌表基于 Knuth《The Art of Computer Programming》中的算法。包含一个 256 个元素的洗牌表周期约 231。适合玩具场景生产代码不建议使用。引擎适配器discard_block_engine丢弃部分输出提升质量ranlux 基于此independent_bits_engine改变输出位宽shuffle_order_engine用洗牌表缓存输出knuth_b 基于此分布详解uniform_int_distribution——均匀分布整数rand() % n的正确替代方案。零偏差闭区间 [a, b]。std::mt19937eng(std::random_device{}());std::uniform_int_distributionintdist(1,6);// 骰子for(inti0;i10;i)std::coutdist(eng) ;// 1~6 均匀分布normal_distribution——正态分布Box-Muller 变换底层使用 Box-Muller 变换将两个独立的 [0,1) 均匀分布映射为两个独立的标准正态分布。z0 sqrt(-2 * ln u1) * cos(2π * u2) z1 sqrt(-2 * ln u1) * sin(2π * u2)std::mt19937eng(std::random_device{}());std::normal_distributiondoubledist(170.0,5.0);// 均值 170标准差 5for(inti0;i5;i)std::coutdist(eng)\n;// 模拟身高大部分在 160~180C11 起标准要求此实现但具体算法由库决定。VS 和 libstdc 均采用 Box-Muller。bernoulli_distribution——伯努利分布以概率 p 返回true以概率 1−p 返回false。适合抽奖、A/B 测试等二值随机实验。std::mt19937eng(std::random_device{}());std::bernoulli_distributiondist(0.7);// 70% trueintcount0;for(inti0;i10000;i)if(dist(eng))count;std::couttrue 比例: count/10000.0\n;// 接近 0.7std::seed_seq——真种子初始化引擎默认种子或固定种子会导致同一进程内两次运行结果相同。用std::random_device真随机数生成器通常基于硬件熵源初始化种子序列#includerandomintmain(){std::random_device rd;std::seed_seq seed{rd(),rd(),rd(),rd(),rd(),rd(),rd(),rd()};std::mt19937eng(seed);// 用 8 个真随机数扩展填充 2.5 KB 状态std::uniform_int_distributionintdist(0,100);for(inti0;i5;i)std::coutdist(eng)\n;return0;}seed_seq内部按梅森旋转算法的参数做了混洗shuffle保证即使种子之间有简单模式状态初始化也是高质量的。注意std::random_device在 MinGW 下可能退化为伪随机此时可考虑用std::chrono::system_clock::now().time_since_epoch().count()参与种子。面试题集Q1rand() % n为什么不均匀A当n不能整除RAND_MAX 1时剩余部分(RAND_MAX 1) % n个数映射到前几个桶导致低值偏大。正确做法为标准库的uniform_int_distribution内部做拒绝采样。Q2mt19937 的名字含义是什么AMersenne Twister梅森旋转19937来自其周期 219937− 1这是一个梅森素数。Q3引擎和分布为什么要分离A单一职责。引擎只负责产生高质量随机比特流分布只负责将比特流映射到目标数学分布。两者可自由组合同一种分布可用不同引擎同一个引擎可喂给不同分布。Q4std::random_device是否一定返回真随机数A不一定。实现依赖于平台熵源。Windows 上用RtlGenRandomLinux 上读/dev/urandom均是真随机。但 MinGW 或某些嵌入式环境可能退化为伪随机生成器。Q5discard_block_engine是怎么工作的A引擎每生成 P 个随机数只保留其中的 R 个丢弃剩下的 P − R 个。通过丢弃输出打破 LCG 或 Mersenne Twister 的短周期结构相关性。ranlux48就是 P 389、R 192 的特化。Q6Box-Muller 变换为什么一次生成两个正态随机数A因 Box-Muller 的数学构造基于两个独立均匀分布做极坐标映射天然产生两个独立的标准正态样本。实际实现通常缓存第二个下次调用时直接返回。Q7线程安全吗A引擎和分布对象都不是线程安全的。多线程场景下每个线程应有独立引擎副本或加互斥锁。C11 未提供线程安全的随机设施。Q8如何生成 [0, 1) 之间的浮点数std::mt19937eng(std::random_device{}());std::uniform_real_distributiondoubledist(0.0,1.0);doublexdist(eng);// [0, 1)注意是半开区间[0, 1)。总结维度rand()random周期231219937分布无需手搓uniform / normal / bernoulli 等偏差% n产生拒绝采样保证无偏扩展性不可扩展引擎 分布自由组合线程安全全局状态对象级线程各自持有接手新项目先删rand()换random——不是你一个人在受益是每个 downstream 调用者都被保护了。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

LlamaIndex BM25Retriever 完全指南:基于 bm25s 的稀疏词法检索器实现原理与实战 2026/9/10 16:26:23

LlamaIndex BM25Retriever 完全指南:基于 bm25s 的稀疏词法检索器实现原理与实战

LlamaIndex BM25Retriever 完全指南:基于 bm25s 的稀疏词法检索器实现原理与实战 【免费下载链接】llama_index LlamaIndex is the leading document agent and OCR platform 项目地址: https://gitcode.com/GitHub_Trending/ll/llama_index 本文围绕 LlamaI…

阅读更多 →
CANN/ge算子动态输出数量获取 2026/9/10 16:26:23

CANN/ge算子动态输出数量获取

GetDynamicOutputNum 【免费下载链接】ge GE(Graph Engine)是面向昇腾的图编译器和执行器,提供了计算图优化、多流并行、内存复用和模型下沉等技术手段,加速模型执行效率,减少模型内存占用。 GE 提供对 PyTorch、Tenso…

阅读更多 →
探索未来通讯新体验:AyuGram - 更加精致的Telegram客户端 2026/9/10 16:26:23

探索未来通讯新体验:AyuGram - 更加精致的Telegram客户端

探索未来通讯新体验:AyuGram - 更加精致的Telegram客户端 项目简介 AyuGram是一款创新的、功能丰富的Telegram客户端,旨在提供超越原生应用的用户体验。其特色在于全透明模式(灵活可调)、消息历史记录保存、反撤回功能等&#xf…

阅读更多 →
Calibre 电子书格式转换教程:30 秒完成第一次转换,一键批量处理整个书库 2026/9/10 16:26:23

Calibre 电子书格式转换教程:30 秒完成第一次转换,一键批量处理整个书库

Calibre 电子书格式转换教程:30 秒完成第一次转换,一键批量处理整个书库 【免费下载链接】calibre The official source code repository for the calibre ebook manager 项目地址: https://gitcode.com/GitHub_Trending/ca/calibre 你下载的扫描…

阅读更多 →
MATLAB Simulink智能小车PID闭环建模与验证 2026/9/10 16:26:23

MATLAB Simulink智能小车PID闭环建模与验证

简介:本资源是一份面向自动化、控制工程及机电类本科生的PID控制智能小车MATLAB仿真课程设计完整实现方案,聚焦闭环控制原理验证与工程建模实践,适用于课程设计、期末大作业及控制算法入门学习。压缩包共8个文件,含2个核心MATLAB脚…

阅读更多 →
JAVA毕设选题推荐:基于 SpringBoot 的建设工程项目管理平台的设计与实现 基于 SpringBoot 的建筑工程信息管理系统【附源码、mysql、文档、调试+代码讲解+全bao等】 2026/9/10 16:23:21

JAVA毕设选题推荐:基于 SpringBoot 的建设工程项目管理平台的设计与实现 基于 SpringBoot 的建筑工程信息管理系统【附源码、mysql、文档、调试+代码讲解+全bao等】

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞