【问题标题】:Generate random numbers with logarithmic distribution and custom slope生成具有对数分布和自定义斜率的随机数
【发布时间】:2015-08-23 13:35:33
【问题描述】:

我正在尝试生成具有对数分布的随机整数。我使用以下公式:

idx = Math.floor(Math.log((Math.random() * Math.pow(2.0, max)) + 1.0) / Math.log(2.0));

这很有效,并且在 1000 次迭代中产生这样的序列(每个数字代表该索引生成了多少次):

[525, 261, 119, 45, 29, 13, 5, 1, 1, 1]

Fiddle

我现在正在尝试调整此分布的斜率,使其不会下降得那么快并产生如下内容:

[150, 120, 100, 80, 60, ...]

盲目地玩系数并没有给我想要的东西。任何想法如何实现它?

【问题讨论】:

标签: javascript algorithm math statistics distribution


【解决方案1】:

您提到了对数分布,但看起来您的代码旨在生成截断的几何分布,尽管它存在缺陷。有不止一种分布称为对数分布,它们都不是那么常见。请澄清您是否真的是指其中之一。

您计算 floor[log_2 U],其中 U 从 1 均匀分布到 (2^max)+1。这有 1/2^max 机会产生最大值,但您将其限制为 max-1。所以,你有 1/2^max 机会产生 0, 2/2^max 机会产生 1, 4/2^max 机会产生 2,... 最多 1/2 + 1/2^max产生max-1的机会。

存在于您的代码中,但问题的描述中缺少的是您正在使用

翻转计算的索引
idx = (max-idx) - 1

在此之后,您产生 0 的机会是 1/2 + 1/2^max,而您产生 k 值的机会是 1/2^(k+1)。

我认为让 U 在 [1,2^max+1] 上一致是错误的。相反,我认为您希望 U 在 [1,2^max] 上保持一致。那么你生成 idx=k 的机会是 2^(max-k-1)/((2^max)-1)。

idx = Math.floor(Math.log((Math.random()*(Math.pow(2.0, max)-1.0)) + 1.0) / Math.log(2.0));

zmii 的评论是,您可以通过将两个 2.0 替换为更接近 1.0 的值来获得更平坦的分布,这很好。它对较小的 max 值产生不令人满意的结果的原因是您从 [1,1.3^max+1] 而不是 [1,1.3^max] 均匀采样。当 max 较小且 base 较小时,额外的 +1 会产生较大的差异。请尝试以下操作:

var zmii = 1.3;
idx = Math.floor(Math.log((Math.random()*(Math.pow(zmii, max)-1.0))+1.0) / Math.log(zmii));

【讨论】:

    猜你喜欢
    • 2011-03-07
    • 2017-05-10
    • 2011-04-14
    • 1970-01-01
    • 2011-05-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多