随机数 std.random¶
基础概念¶
Lumos 提供高效的伪随机数生成(PRNG)支持,采用梅森旋转算法实现,具有良好的统计特性和性能。
全局随机数函数¶
初始化种子¶
// 使用整数种子初始化
act[sys.rand] srand(i32 seed) -> unit;
act[sys.rand] srand(i64 seed) -> unit;
act[sys.rand] srand(u32 seed) -> unit;
act[sys.rand] srand(u64 seed) -> unit;
// 使用系统时间初始化(自动)
act[sys.rand] srand_auto() -> unit;
// 使用设备随机性初始化
act[sys.rand] srand_secure() -> unit;
整数随机数¶
// 生成随机整数 [0, INT_MAX]
fun rand() -> i32;
// 特定位宽的随机整数
fun rand8() -> u8;
fun rand16() -> u16;
fun rand32() -> u32;
fun rand64() -> u64;
// 范围内的随机整数 [min, max]
fun rand_range(i32 min, i32 max) -> i32;
fun rand_range_u32(u32 min, u32 max) -> u32;
fun rand_range_u64(u64 min, u64 max) -> u64;
// n 位的随机整数
fun randbits(usize n) -> u64;
浮点随机数¶
// 生成 [0, 1) 范围的浮点数
fun randf() -> f32;
fun randf64() -> f64;
// 生成指定范围的浮点数 [min, max)
fun randf_range(f32 min, f32 max) -> f32;
fun randf_range64(f64 min, f64 max) -> f64;
// 生成正态分布的随机数(中心值 0,标准差 1)
fun randn() -> f32;
fun randn64() -> f64;
// 生成指定均值和标准差的正态分布
fun randn_normal(f32 mean, f32 stddev) -> f32;
fun randn_normal64(f64 mean, f64 stddev) -> f64;
布尔随机数¶
// 生成随机布尔值
fun randb() -> bool;
// 生成概率为 p 的布尔值(p 范围 [0.0, 1.0])
fun randb_prob(f32 p) -> bool;
随机数生成器类¶
对于需要维持独立随机数状态的场景,可以使用 RNG 类。
RNG 类定义¶
RNG {
// 创建随机数生成器
fun new() -> RNG;
// 使用种子创建
fun with_seed(i64 seed) -> RNG;
// 设置种子
fun seed(i64 seed) -> unit;
// 重置生成器
fun reset() -> unit;
}
RNG 方法¶
RNG {
// 生成随机整数 [0, INT_MAX]
fun next_i32() -> i32;
fun next_u32() -> u32;
fun next_u64() -> u64;
// 生成范围内的整数
fun next_i32_range(i32 min, i32 max) -> i32;
fun next_u32_range(u32 min, u32 max) -> u32;
fun next_u64_range(u64 min, u64 max) -> u64;
// 生成浮点数 [0, 1)
fun next_f32() -> f32;
fun next_f64() -> f64;
// 生成浮点数 [min, max)
fun next_f32_range(f32 min, f32 max) -> f32;
fun next_f64_range(f64 min, f64 max) -> f64;
// 生成正态分布
fun next_gaussian() -> f32;
fun next_gaussian64() -> f64;
// 生成布尔值
fun next_bool() -> bool;
fun next_bool_prob(f32 p) -> bool;
// 生成 n 位随机数
fun next_bits(usize n) -> u64;
}
RNG 类型转换¶
RNG {
// 转换为 i32
fun as_i32() -> i32;
// 转换为 f32
fun as_f32() -> f32;
// 转换为 bool
fun as_bool() -> bool;
}
特殊分布¶
指数分布¶
// 参数为 lambda 的指数分布
fun exponential(f32 lambda) -> f32;
fun exponential64(f64 lambda) -> f64;
// 使用 RNG 对象
fun RNG::next_exponential(f32 lambda) -> f32;
泊松分布¶
// 参数为 lambda 的泊松分布
fun poisson(f32 lambda) -> i32;
// 使用 RNG 对象
fun RNG::next_poisson(f32 lambda) -> i32;
二项分布¶
// 参数为 n, p 的二项分布
fun binomial(i32 n, f32 p) -> i32;
// 使用 RNG 对象
fun RNG::next_binomial(i32 n, f32 p) -> i32;
均匀分布(向量)¶
// 在 n 维单位球内的均匀分布
fun sphere(usize n) -> [f32];
// 在 n 维球面上的均匀分布
fun sphere_surface(usize n) -> [f32];
使用示例¶
全局随机函数¶
use std.random.*;
act main() {
// 初始化种子
srand_auto();
// 生成整数
i32 num = rand();
i32 range = rand_range(1, 100);
println("Random number: {}", range);
// 生成浮点数
f32 decimal = randf();
f32 prob = randf_range(0.0, 1.0);
// 生成正态分布
f32 normal = randn();
println("Normal: {}", normal);
// 生成布尔值
bool coin = randb();
if coin {
println("Heads!");
} else {
println("Tails!");
}
}
使用 RNG 对象¶
use std.random.*;
act main() {
// 创建独立的随机数生成器
var rng = RNG::with_seed(12345);
// 生成一系列随机数
for i in 0..10 {
i32 num = rng.next_i32_range(1, 100);
println("{}", num);
}
// 生成不同分布的随机数
f32 uniform = rng.next_f32();
f32 normal = rng.next_gaussian();
i32 poisson = rng.next_poisson(3.0);
println("Uniform: {}", uniform);
println("Normal: {}", normal);
println("Poisson: {}", poisson);
}
蒙特卡洛方法估算 π¶
use std.random.*;
act main() {
// 使用蒙特卡洛方法估算 π
i32 samples = 1000000;
i32 inside = 0;
srand_auto();
for i in 0..samples {
f32 x = randf_range(0.0, 1.0);
f32 y = randf_range(0.0, 1.0);
if x * x + y * y <= 1.0 {
inside = inside + 1;
}
}
f32 pi_estimate = (inside as f32 / samples as f32) * 4.0;
println("Estimated π: {}", pi_estimate);
}
加权随机选择¶
use std.random.*;
use std.container.*;
act main() {
// 权重数组
[f32] weights = [1.0, 2.0, 3.0, 4.0];
// 计算累积权重
var cum_weights = List::<f32>::new();
var sum = 0.0;
for w in weights {
sum = sum + w;
cum_weights.push(sum);
}
// 随机选择
srand_auto();
f32 r = randf_range(0.0, sum);
for i in 0..cum_weights.length {
if r <= cum_weights.at(i) {
println("Selected index: {}", i);
break;
}
}
}
性能建议¶
- 单线程程序:使用全局随机函数(自动管理状态)
- 多线程程序:每个线程使用独立的 RNG 对象(避免同步开销)
- 需要可重现性:使用固定种子初始化
- 需要密码学安全:使用
srand_secure()或专门的密码学 RNG 库 - 性能敏感:避免频繁调用正态分布或特殊分布,考虑缓存结果
质量保证¶
Lumos 的随机数生成器采用 MT19937 算法,具有以下特性:
- 周期:2^{19937} - 1,足够大用于大多数应用
- 统计特性:通过 Diehard 测试和现代统计测试
- 性能:约 1GB/s 的随机数生成速度
- 线程安全:全局函数使用线程本地存储;RNG 对象需要显式同步
相关内容:数值类型见 类型系统。