3.7 随机值
2 分钟阅读
既然有了产生随机数据的方法,如何将其转换为我们想要的值类型?
这是个「陷阱」式问题:我们需要同时知道想要的范围和值的分布类型(这正是下一节的内容)。
Rng trait
为方便起见,所有生成器自动实现 Rng trait,它提供了几种生成值的快捷方式。其中有若干产生均匀分布值的便捷函数:
Rng::random从适合该类型的范围生成无偏(均匀)随机值。对整数通常是完整可表示范围(例如从0u32到std::u32::MAX),对浮点数是 0 到 1 之间,还支持数组、元组等其他类型。该方法是
StandardUniform分布的便捷封装,详见下一节。Rng::random_range在给定范围内生成无偏随机值Rng::fill和Rng::try_fill是用随机值填充任意字节或整数切片的优化函数
还有产生非均匀布尔值的便捷函数:
Rng::random_bool以给定概率生成布尔值Rng::random_ratio也以分数形式定义概率生成布尔值
最后,有从任意分布采样的函数:
Rng::sample直接从某种分布采样
示例:
| |
此外,random 函数是对 rng() 上 Rng::random 的快捷方式:
| |
自定义随机类型
注意上面 rng.random() 根据类型产生不同分布的值:
i32值从i32::MIN ..= i32::MAX均匀采样f32值从0.0 .. 1.0均匀采样
这就是 StandardUniform 分布。Distribution 是下一章的主题,但鉴于 StandardUniform 的重要性,在此介绍。惯例多少有些任意,但按合理逻辑选择:
- 值均匀采样:给定任意两个等长子范围,每个包含下一个采样值的概率相等
- 通常使用目标类型的整个范围
- 对
f32和f64使用0.0 .. 1.0范围(不含1.0),原因有二:(a) 这是随机数生成器的常见做法;(b) 对许多用途而言,在实数轴上均匀分布的样本很重要,而对浮点表示这只能通过限制范围实现。
据此,我们可以为自己的类型实现 StandardUniform 分布:
| |