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

如何基于自定义distribution函数创建指定分布的随机数生成函数

自定义分布随机数生成器的优化方案

你的核心需求是根据给定的distribution(x)函数生成随机值,让y值越高的x出现概率越大,现有方案的问题出在固定阈值筛选逻辑和低效的样本生成方式上,以下是更可靠的实现思路和代码:

现有代码的问题

  • 用固定的e值做筛选,没有把每个x对应的y值(概率密度)纳入判断,完全无法准确拟合目标分布
  • 每次生成100个样本再排序筛选,不仅效率低,还可能因为运气差陷入无限循环
  • 没必要依赖d3的range方法,纯JS就能完成核心逻辑

推荐方案:接受-拒绝采样(Accept-Reject Sampling)

这是生成自定义分布随机数的标准方法,逻辑完全贴合你的需求,不需要手动调阈值:

  1. 先确定distribution(x)在x∈[0,1]范围内的最大值M(确保M大于等于所有x对应的y值)
  2. 生成一个随机x(范围[0,1])
  3. 生成一个随机u(范围[0,M])
  4. 如果u ≤ distribution(x),就返回这个x;否则重复步骤2-4

实现代码

// 先实现一个工具函数,获取distribution的最大值M
function getDistributionMax(fn, sampleCount = 1000) {
  let maxY = 0;
  for (let i = 0; i < sampleCount; i++) {
    const x = Math.random();
    const y = fn(x);
    if (y > maxY) maxY = y;
  }
  // 留一点余量避免漏判
  return maxY * 1.05;
}

// 最终的distributor函数
function distributor(fn) {
  const M = getDistributionMax(fn);
  while (true) {
    const x = Math.random();
    const y = fn(x);
    const u = Math.random() * M;
    if (u <= y) {
      return x;
    }
  }
}

说明

  • getDistributionMax通过采样1000个x值找到分布的近似最大值,乘以1.05是为了避免因为采样不够漏过真实最大值
  • 循环里的逻辑完全基于每个x对应的y值判断:y值越高,u ≤ y的概率越大,x被选中的概率就越高,完美贴合你的需求
  • 不需要再手动调e参数,所有逻辑都由目标分布本身决定

额外优化建议

如果你的distribution(x)有已知的理论最大值(比如你通过图形编辑器能直接看到峰值),可以直接把M设为这个值,省去采样找最大值的步骤,效率更高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 02:10:18