gpt4 book ai didi

c# - 生成高斯范围内的随机数?

转载 作者:太空狗 更新时间:2023-10-29 21:36:24 51 4
gpt4 key购买 nike

我想使用随机数生成器在高斯范围内创建随机数,我可以自己定义中位数。我已经在这里问过类似的问题,现在我正在使用这段代码:

class RandomGaussian
{

private static Random random = new Random();
private static bool haveNextNextGaussian;
private static double nextNextGaussian;

public static double gaussianInRange(double from, double mean, double to)
{
if (!(from < mean && mean < to))
throw new ArgumentOutOfRangeException();

int p = Convert.ToInt32(random.NextDouble() * 100);
double retval;
if (p < (mean * Math.Abs(from - to)))
{
double interval1 = (NextGaussian() * (mean - from));
retval = from + (float)(interval1);
}
else
{
double interval2 = (NextGaussian() * (to - mean));
retval = mean + (float)(interval2);
}
while (retval < from || retval > to)
{
if (retval < from)
retval = (from - retval) + from;
if (retval > to)
retval = to - (retval - to);
}
return retval;
}

private static double NextGaussian()
{
if (haveNextNextGaussian)
{
haveNextNextGaussian = false;
return nextNextGaussian;
}
else
{
double v1, v2, s;
do
{
v1 = 2 * random.NextDouble() - 1;
v2 = 2 * random.NextDouble() - 1;
s = v1 * v1 + v2 * v2;
} while (s >= 1 || s == 0);
double multiplier = Math.Sqrt(-2 * Math.Log(s) / s);
nextNextGaussian = v2 * multiplier;
haveNextNextGaussian = true;
return v1 * multiplier;
}
}
}

然后为了验证结果,我用 gaussianInRange(0, 0.5, 1) for n=100000000 绘制了它们 enter image description here

正如您所看到的那样,中位数实际上是 0.5,但实际上并没有可见的曲线。那我做错了什么?

编辑

我想要的是这样的东西,我可以通过传递一个值来自己设置最高概率。

enter image description here

最佳答案

绘制以特定范围内为条件的正态偏差的最简单方法是使用拒绝抽样:

do {
retval = NextGaussian() * stdev + mean;
} while (retval < from || to < retval);

当您在无条件法线生成器中绘制圆圈中的坐标(v1v2)时,会使用相同类型的东西。

简单地折叠范围外的值不会产生相同的分布。


此外,如果您很好地实现了 error function及其倒数,您可以使用倒数直接计算值 CDF .正态分布的 CDF 是

F(retval) = (1 + erf((retval-mean) / (stdev*sqrt(2)))) / 2

删失分布的 CDF 是

C(retval) = (F(retval) - F(from)) / (F(to) - F(from)), from ≤ x < to

要使用 CDF 绘制随机数,您可以从 [0, 1] 上的均匀分布绘制 v 并求解 C(retval) = v。这给出了

double v = random.NextDouble();
double t1 = erf((from - mean) / (stdev*sqrt(2)));
t2 = erf((to - mean) / (stdev*sqrt(2)));
double retval = mean + stdev * sqrt(2) * erf_inv(t1*(1-v) + t2*v);

您可以预先计算特定参数的t1t2。这种方法的优点是没有拒绝抽样,因此每次绘制只需要一个 NextDouble()。如果 [from, to] 间隔很小,这会更快。


但是,听起来您可能想要 binomial distribution相反。

关于c# - 生成高斯范围内的随机数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5281672/

51 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com