如何创建一个生成随机数但遵循特定分布的函数

How to create a function that generate a random number but following a specific distribution

提问人:pernifloss 提问时间:8/4/2023 最后编辑:pernifloss 更新时间:8/4/2023 访问量:48

问:

我喜欢创建数据可视化,但我经常需要生成数据,我发现随机正态分布太“无聊”了。

我想创建一个遵循指定分布的随机值生成器。

我的想法是使用图形编辑器,例如:

https://observablehq.com/d/ac77643d0cd9422e

在这个编辑器中,我有一个函数可以返回图表上的值。distribution(x)y

我想创建一个返回随机值的函数,但如果图上的值很高,则该值有更多的“机会”是 a。distributor(distribution)xy

编辑: 我添加了一个分配器函数,可以创建 100 对的样本,对它们进行排序,并有机会继续迭代它......它有点有效,但很糟糕。而且我不知道哪个值更适合曲线......x,yy100 * ee

distributor = (fn, e = 0.9) => {
  let find = () =>
    d3
      .range(0, 100)
      .map(() => {
        let x = Math.random();
        return { y: fn(x), x };
      })
      .sort((a, b) => b.y - a.y)
      .find((x) => Math.random() > e);
  while (true) {
    let f = find();
    if (f) {
      return f.x;
    }
  }
}

谢谢

JavaScript 随机 可视化 数据生成

评论

1赞 Sam Mason 8/4/2023
AFAICT 你只需要生成统一的值,然后根据你的函数(或者可能是它的倒函数)进行转换。distribution
0赞 pernifloss 8/4/2023
嗯,看曲线定义 observablehq.com/@nhogs/easing-graphs-editor,没办法理解反转它......
0赞 Sam Mason 8/4/2023
也许您可以更改曲线的定义,以便您可以使用统一变量调用它?

答:

1赞 pernifloss 8/4/2023 #1

受 https://prosepoetrycode.potterpcs.net/2015/05/weighted-random-choices-js/ 的启发我最终使用了:

distributor = (fn, nbVal = 20) => {
  let weights = d3.range(nbVal).map((d) => fn(d / nbVal));
  var totalWeight = 0;
  totalWeight += weights.reduce((acc, v) => acc + v);
  var random = Math.random() * totalWeight;
  for (var i = 0; i < nbVal; i++) {
    random -= weights[i];
    if (random < 0) {
      return i / nbVal;
    }
  }
}

缺点 : You can only generate a disrete amount of value