9

我搜索了该站点,但没有找到我正在寻找的确切内容......我想从正态分布中生成一个离散的随机数。

例如,如果我的范围最小为 4,最大为 10,平均为 7。我需要什么代码或函数调用(Objective C 首选)返回该范围内的数字。自然,由于正态分布,返回的更多数字将以 7 为中心。

作为第二个例子,钟形曲线/分布是否可以偏向另一端?假设我需要生成一个范围最小为 4 和最大为 10 的随机数,并且我希望大多数数字返回以数字 8 为中心,并基于倾斜的钟形曲线自然下降。

任何帮助是极大的赞赏....

安东尼

4

5 回答 5

4

你需要这个做什么?你能按照掷骰子玩家的方式来做吗?

生成 2 到 5(当然也包括在内)范围内的两个随机整数并将它们相加。或掷硬币 (0,1) 六次,结果加 4。

将多个骰子相加会产生正态分布(“钟形曲线”),而消除高掷或低掷可用于以各种方式扭曲分布。

关键是您要使用离散数字(我希望您指的是整数)。多次掷骰子会产生正态分布。事实上,我认为这就是我们在学校第一次接触高斯曲线的方式。


当然,投掷次数越多,您就越接近钟形曲线。滚动单个模具会产生一条平线。掷两个骰子只会产生一个与钟声不太接近的上下坡道。六个硬币翻转让你更接近。

所以考虑这个...

如果我正确理解您的问题,您只有七种可能的结果——整数 (4,5,6,7,8,9,10)。您可以设置一个包含七个概率的数组来近似您喜欢的任何分布。

于 2009-07-29T00:31:46.913 回答
1

是的,有复杂的数学解决方案,但对于“简单但实用”,我会同意 Nosredna 的评论。对于一个简单的 Java 解决方案:

Random random=new Random();
public int bell7()
{
  int n=4;
  for (int x=0;x<6;++x)
    n+=random.nextInt(2);
  return n;
}

如果您不是 Java 人员,Random.nextInt(n) 会返回一个介于 0 和 n-1 之间的随机整数。我认为其余的应该与您在任何编程语言中看到的相似。

如果范围很大,那么我会在其中使用更大的数字而不是 nextInt(2),这样循环中的迭代次数就会减少,具体取决于调用频率和性能要求。

于 2009-07-29T16:50:57.683 回答
1

丹戴尔和杰是完全正确的。你真正想要的是二项分布,而不是正态分布。二项分布的形状看起来很像正态分布,但它是离散且有界的,而正态分布是连续且无界的。

Jay 的代码生成一个包含 6 次试验的二项分布,每次试验的成功概率为 50%。如果您想“倾斜”您的分布,只需更改决定是否将 1 添加到 n 的行,以使概率不是 50%。

于 2009-08-12T04:49:30.063 回答
1

正态分布不是由它的端点来描述的。通常它是用它的平均值(你给它的7)和它的标准差来描述的。这样做的一个重要特征是,有可能从这个分布中得到一个远远超出预期范围的值,尽管这将是非常罕见的,你离平均值越远。

从分布中获取值的常用方法是从均匀分布中生成随机值,例如,这很容易完成,rand()然后将其用作累积分布函数的参数,该函数将概率映射到上界限。对于标准分布,这个函数是

F(x) = 0.5 - 0.5*erf( (x-μ)/(σ * sqrt(2.0)))

哪里erf()是可以用泰勒级数描述的误差函数:

erf(z) = 2.0/sqrt(2.0) * Σ ∞</sup> n=0 ((-1) n z 2n + 1 )/(n!(2n + 1))

我将把它作为一个练习来翻译成 C。

如果你不想参与这个练习,你可以考虑使用Gnu Scientific Library,在许多其他功能中,它具有一种在许多常见分布之一中生成随机数的技术,其中高斯分布(提示)就是其中之一。

显然,所有这些函数都返回浮点值。您将不得不使用一些舍入策略来转换为离散值。一种有用(但幼稚)的方法是简单地向下转换为整数。

于 2009-07-28T23:57:33.677 回答
1

许多框架和库都内置了这个。

此外,就像TokenMacGuy所说的,正态分布的特征不是它定义的区间,而是两个参数:平均值μ和标准差σ。使用这两个参数,您可以将分布的某个分位数限制在某个区间内,以便 95% 的所有点都落在该区间内。但是将其完全限制在 (−∞, ∞) 以外的任何区间是不可能的。

有几种方法可以从均匀随机值生成正态分布值(这是大多数随机或伪随机数生成器正在生成的:

  • Box-Muller 变换可能是最简单的,但计算速度并不快。根据您需要的数字数量,它应该足够了,而且绝对很容易编写。

  • 另一种选择是 Marsaglia 的Polar 方法,该方法通常更快1

  • 第三种方法是Ziggurat 算法,它的计算速度要快得多,但编程要复杂得多。不过,在真正使用大量随机数的应用程序中,它可能是最佳选择。

不过,作为一般建议:如果您可以访问已经为您生成正态分布随机数的库,请不要自己编写。


为了使您的分布倾斜,我只使用常规正态分布,为曲线的一侧适当地选择μσ,然后确定一个点落在您想要的均值的哪一侧,适当地拉伸它以适应您想要的分布。


对于仅生成整数,我建议您在随机数恰好落在您所需的区间内时向最接近的整数四舍五入,如果不是,则拒绝它(然后绘制一个新的随机数)。这样您就不会人为地扭曲分布(例如,如果您将值分别钳制为 4 或 10)。


1在使用故意坏的随机数生成器(是的,比 RANDU 更差)进行测试时,我注意到极坐标方法会导致无限循环,拒绝每个样本。但是,对于满足他们通常的统计期望的随机数不会发生。

于 2009-07-29T00:15:23.333 回答