【问题标题】:random value generator with normal distribution for objective-c用于objective-c的具有正态分布的随机值生成器
【发布时间】:2024-01-12 16:21:02
【问题描述】:

我想将数字生成到具有正态分布的数组中。 Objective-c 或 c 中是否有任何函数可以帮助轻松获得结果而无需任何数学运算?

【问题讨论】:

  • 你说得对,但我认为有一些方法可以帮助实现这一目标变得更容易
  • 这可能会有所帮助:*.com/questions/12948293/…

标签: ios objective-c c normal-distribution


【解决方案1】:

使用 Box-Muller-Transformation:

1.) 你需要两个均匀分布的随机数 u 和 v 作为区间 (0,1] 中的双精度数(需要排除 0):

double u =(double)(random() %100000 + 1)/100000; //for precision
double v =(double)(random() %100000 + 1)/100000; //for precision

2.) 计算均值为0,标准差sigma为1的均匀分布值:

double x = sqrt(-2*log(u))*cos(2*pi*v);   //or sin(2*pi*v)

3.) 如果需要,为您的目标分布添加 sigma 和平均值,如下所示:

double y = x * sigmaValue + averageValue;

4.) 将其放入数组中

[randomNumberArray addObject:[NSNumber numberWithDouble:y]]

objc 没有函数norminv。所以,这里需要数学。

编辑:我喜欢使用random() 来播种随机值生成器

【讨论】:

  • 这确实是一个很好的解决方案,但有一个问题:这是否会对数字进行排序?
  • 不幸的是它不会。并且(对于大型数组)请考虑检查并排除 u 和 v 的值 0 和 1。否则日志功能将不起作用。
  • 事后用[randomNumberArray sortedArrayUsingSelector:@selector(compare:)]排序有什么问题?
  • @dwbrito,它也会生成负数。如果您遵循方程式直到第 2 步,它将生成平均值为零的正态分布值(例如:regentsprep.org/Regents/math/algtrig/ATS2/normal67.gif)。所以,会有正值和负值。
  • @dwbrito,不,它不仅仅是产生负值。 Ziggurat 算法实际上与 Box-Muller 变换类似,但实现起来并不容易。
【解决方案2】:

让我先说,如果我错了,请纠正我!

据我了解,Box-Muller 变换依赖于源数字,它们本身是均匀分布的,因此使用 random() 或 rand() 作为 Box-Muller 的源数据集不会 必然产生均匀分布。

它旨在采用一组通用的均匀分布的随机数,并生成在二维坐标系中均匀分布的独立随机数对。

Wikipedia: Box-Muller Transform


还有另一种方法:

在使用 rand48 函数库的大多数 Unix 系统(以及 iOS 或 OSX 上的 Objective C)上:

Reference: drand

double drand48(void);
void srand48(long int seedval);

srand48() 生成生成器的种子,drand48() 生成在区间 [0.0 - 1.0] 上均匀分布的随机数

【讨论】:

  • 感谢您的有趣讨论。只要在 (0,1] 的区间内有两个独立的均匀分布值,Box-Muller 方法就应该生成正态分布值。但我同意随机数生成器的源质量对结果有影响。我不'不喜欢random() 的质量,但我需要用正态分布的数字创建相同的序列。这就是为什么我不能使用 arc4random() 或其他更好的方法。我将如何在 iOS 中实现这些 Unix 函数?
  • 正如@Adam 所说,srand48() 和 drand48() 函数在 iOS 中可用。
最近更新 更多