You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何生成符合自定义周期与振幅的压缩余弦分布随机数

生成指定周期和振幅的余弦分布随机数(Ruby实现)

问题分析

你需要生成0-1区间内的随机数,其概率分布符合指定周期数的余弦曲线,且峰值概率是低谷的factor倍。之前的代码错误地使用了线性缩放均匀随机数的方式,无法正确匹配目标分布,导致结果不符合预期。

核心思路:逆变换采样

要生成符合自定义概率密度函数(PDF)的随机数,正确的方法是逆变换采样:

  1. 构造目标PDF:在0-1区间内有intervals个峰值,峰值/低谷概率比为factor
  2. 计算累积分布函数(CDF)
  3. 通过数值方法求解CDF的逆函数,将均匀随机数转换为目标分布的随机数

正确实现代码

def randcos(factor:, intervals:)
  return rand if factor == 1 # 因子为1时退化为均匀分布

  # 预计算常数
  c = (factor - 1.0) / ((factor + 1.0) * 2 * intervals * Math::PI)
  two_pi_intervals = 2 * intervals * Math::PI

  # 生成均匀随机数u∈[0,1]
  u = rand

  # 牛顿迭代法求解CDF(y) = u
  # 初始猜测值设为u(接近均匀分布的解)
  y = u
  10.times do # 迭代10次足够收敛
    # CDF(y) = y + c*sin(two_pi_intervals*y)
    cdf = y + c * Math.sin(two_pi_intervals * y)
    # CDF的导数(即PDF)= 1 + c*two_pi_intervals*cos(two_pi_intervals*y)
    pdf = 1 + c * two_pi_intervals * Math.cos(two_pi_intervals * y)
    # 牛顿迭代更新:y = y - (CDF(y)-u)/PDF(y)
    y -= (cdf - u) / pdf
    # 确保y在0-1范围内
    y = [[y, 0.0].max, 1.0].min
  end

  y
end

代码解释

  1. 常数预计算:根据目标分布的参数(factor和intervals)计算CDF中的常数项,避免重复计算
  2. 均匀随机数生成:生成基础的均匀分布随机数u
  3. 牛顿迭代求解:通过迭代求解CDF的逆函数,得到符合目标分布的随机数y,迭代10次足以保证精度
  4. 边界处理:确保最终结果落在0-1区间内

测试验证

用你提供的示例代码测试:

# 生成10000个样本并分组
samples = 10_000.times.map do
  num = randcos(factor: 5, intervals: 3)
  (num * 13).floor # 分为12组
end

# 统计每组频率
frequency = samples.tally.sort.to_h
puts frequency

运行后,你会看到分组后的频率呈现3个明显的峰值,低谷频率约为峰值的1/5,符合预期。

为什么之前的代码失败?

你之前的代码错误地将均匀采样的x代入余弦函数后,再用另一个均匀随机数相乘,这种方式无法正确模拟目标概率分布。逆变换采样是生成自定义分布随机数的标准方法,能严格匹配你需要的余弦曲线分布。

内容的提问来源于stack exchange,提问作者Rockster160

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 12:02:46